Thread和Runnable、run和start的區別


多線程可以通過兩種方式來創建:

一、通過繼承Thread類。

二、通過實現Runnable接口。

那么中兩種方式到底有什么區別呢?那種方式更好些呢?

先看看幾個簡單的Demo:

Demo1

public class MyThread {

    public static void main(String[] args) {
        ThreadTest t = new ThreadTest();
        t.start();
        t.start();
        t.start();
        t.start();
    }
}

class ThreadTest extends Thread {
    private int n = 10;

    @Override
    public void run() {
        while (n > 0) {
            System.out.println(Thread.currentThread().getName() + "  "
                    + n--);
        }
    }
}

運行后可以看出,其實只啟動了一個線程,而且還拋異常了,這個在下面說。

我們修改一下代碼:

Demo2

public class MyThread {

    public static void main(String[] args) {
        new ThreadTest().start();
        new ThreadTest().start();
        new ThreadTest().start();
        new ThreadTest().start();
    }
}

class ThreadTest extends Thread {
    private int n = 10;

    @Override
    public void run() {
        while (n > 0) {
            System.out.println(Thread.currentThread().getName() + "  "
                    + n--);
        }
    }
}

再次運行,發現這四個線程對象各自占有各自的資源,並不是同時完成統一任務。

我們可以得出結論:Thread類實際上無法達到資源共享的目的。

那么,Runnable接口能不能達到這一目的呢?

Demo3

public class MyThread {

    public static void main(String[] args) {
        RunnableTest r = new RunnableTest();
        new Thread(r).start();
        new Thread(r).start();
        new Thread(r).start();
        new Thread(r).start();
    }
}class RunnableTest implements Runnable {
    private int n = 10;

    @Override
    public void run() {

        while (n > 0) {
            System.out.println(Thread.currentThread().getName() + "  "
                    + n--);

        }
    }
}

運行后我們發現,這四個線程同時完成了統一的任務,可以達到資源共享的目的

通過以上比較我們即可得出Thread與Runnable的區別:

1、Runnable適合於多個相同程序代碼線程去處理統一資源的情況,把虛擬的cpu(線程)同程序的代碼,數據有效分離,較好體現面向對象的編程的思想

2、Runnable可以避免由於java的單繼承機制帶來的局限。可以再繼承其他類的同時,還能實現多線程的功能。

3、Runnable能增加程序的健壯性。代碼能夠被多個線程共享。

 

我們把Demo1的線程start()方法改成run()試試

public class MyThread {

    public static void main(String[] args) {
        ThreadTest t = new ThreadTest();
        t.run();
        t.run();
        t.run();
        t.run();
    }
}

class ThreadTest extends Thread {
    private int n = 10;

    @Override
    public void run() {
        while (n > 0) {
            System.out.println(Thread.currentThread().getName() + "  "
                    + n--);
        }
    }
}

運行后結果:

把Demo2的所有線程的start方法改成run試試

public class MyThread {

    public static void main(String[] args) {
        new ThreadTest().run();
        new ThreadTest().run();
        new ThreadTest().run();
        new ThreadTest().run();
    }
}

class ThreadTest extends Thread {
    private int n = 10;

    @Override
    public void run() {
        while (n > 0) {
            System.out.println(Thread.currentThread().getName() + "  "
                    + n--);
        }
    }
}

運行后結果:

由此我們可以區別:

1、start()方法:啟動一個線程,不能多次啟動一個線程。

2、run()方法:在本線程內調用run()方法,可以重復多次調用。

3、用start()方法來啟動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。

4、run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是只有一條,還是要順序執行,要等待run方法體執行完畢后才可繼續執行下面的代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM