Java中 Thread 與 Runnable 的區別

多線程實現方式

  1. 定義一個線程子類,並繼承Thread類。
  2. 定義一個runnable子類,實現runnable接口,並將該用runnable子類傳遞給一個Thread類對象。

上述使用runnable接口定義多線程的好處

在java中不允許多繼承的存在,若想簡介使用多繼承可以利用接口來實現

若想定義一個已實現某個抽象的父類的線程時,在不使用接口時,無法繼續繼承Thread類,那麼問題就出現了,這也就是使用runnable的好處之所在。

使用runnable接口和繼承Thread類的區別

先看代碼:

  1. 利用同一個runnable子類創建線程
public class Test {

    public static void main(String[] args) {
        Test test = new Test();
        MyRunnable runnable1 = test.new MyRunnable("runnable1: ");
        Thread thread1 = new Thread(runnable1);
        Thread thread2 = new Thread(runnable1);
        thread1.start();
        thread2.start();
    }

    class MyRunnable implements Runnable {
        private String name;

        public MyRunnable(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            for (int i = 0; i < 6; i++) {
                System.out.println(name+" --- "+i+" ");
            }
        }

    }
}

運行結果:
這裏寫圖片描述

  1. 定義不同runnable子類創建線程
public class Test1 {

    public static void main(String[] args) {
        Test1 test = new Test1();
        MyRunnable runnable1 = test.new MyRunnable("runnable1: ");
        MyRunnable runnable2 = test.new MyRunnable("runnable2: ");
        Thread thread1 = new Thread(runnable1);
        Thread thread2 = new Thread(runnable2);
        thread1.start();
        thread2.start();
    }

    class MyRunnable implements Runnable {
        private String name;

        public MyRunnable(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            for (int i = 0; i < 6; i++) {
                System.out.println(name+" --- "+i+" ");
            }
        }

    }
}

運行結果:
這裏寫圖片描述

  1. 通過thread子類創建線程
public class Test2 {

    public static void main(String[] args) {
        Test2 test = new Test2();
        MyThread thread1 = test.new MyThread("MyThread1");
        MyThread thread2 = test.new MyThread("MyThread2");
        thread1.start();
        thread2.start();
    }

    class MyThread extends Thread {
        private String name;

        public MyThread(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            for (int i = 0; i < 6; i++) {
                System.out.println(name+" --- "+i+" ");
            }
        }

    }
}

運行結果:
這裏寫圖片描述

通過上述代碼運行結果可以看出

  1. 通過是用runnable接口創建線程時,多個線程直接會共享同一資源,如thread1和thread2都是打印i的值,但每次打印的結果一樣,即重複打印。這屬於併發,還未涉及到這方面知識的學習,以後研究下
    當然runnable也可以實現非併發
  2. 通過thread子類處理實際上是創建兩個線程去執行run方法的

直接new一個runnable子類對象,然後調用run方法的問題:

  1. 在java中,只有Thread代表一個線程,也就是說只有new 一個Thread或其子類才能創建一個線程。
  2. runnable在使用過程中只表示一個普通的接口而已,跟創建線程無關聯
  3. 線程池的使用原理其實也就是創建一個接受runnable子類的集合,然後不斷衝集合中取出runnable子類,交給線程調用其run()方法,若集合爲空則線程等待。
  4. 它實際上是上一節中講的 內部類或者說匿名內部類
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章