Thread和Runnable、run和start的區別

多線程能夠經過兩種方式來建立:java

1、經過繼承Thread類。編程

2、經過實現Runnable接口。多線程

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

先看看幾個簡單的Demo:spa

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--);
        }
    }
}

運行後能夠看出,其實只啓動了一個線程,並且還拋異常了,這個在下面說。code

咱們修改一下代碼:對象

Demo2blog

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的區別:

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

二、Runnable能夠避免因爲java的單繼承機制帶來的侷限。能夠再繼承其餘類的同時,還能實現多線程的功能。

三、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--);
        }
    }
}

運行後結果:

由此咱們能夠區別:

一、start()方法:啓動一個線程,不能屢次啓動一個線程。

二、run()方法:在本線程內調用run()方法,能夠重複屢次調用。

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

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

相關文章
相關標籤/搜索