Runnable介面實現多執行緒

不入開發不工作發表於2021-01-02

基於Runnable介面實現多執行緒

雖然可以通過Thread類的繼承來實現多執行緒的定義,但是在Java程式裡面對於繼承永遠是存在單繼承侷限的,所以在Java裡面又提供有第二種多執行緒的主體定義結構形式,實現java.lang.Runnable介面,此介面定義如下:

public Interface Runnable{
    public void run();
}

範例:通過Runnable實現多執行緒的主體類

class MyThread implements Runnable{//執行緒的主體類
	private String title;
	public MyThread(String title) {
		this.title = title;
	}
	@Override
	public void run() {
		for(int x = 0;x < 10;x++) {
			System.out.println(this.title + "執行,x = " + x); 
		}
	}
}

但是此時由於不再繼承Thread父類了,那麼對於此時的MyThread類中也不就不再支援有start()方法了,如果不使用start方法是無法進行多執行緒啟動的,那麼這個時候就需要觀察一下Thread類所提供的構造方法了。

構造方法:public Thread(Runnable target);

package cn.mldn.demo;

public class ThreadDemo {
	public static void main(String[] args) {
		Thread threadA = new Thread(new MyThread("多執行緒A"));	//通過Thread類的構造方法傳入Runnable物件
		Thread threadB = new Thread(new MyThread("多執行緒B"));
		Thread threadC = new Thread(new MyThread("多執行緒C"));
		threadA.start();//啟動多執行緒
		threadB.start();
		threadC.start();
	}
}

class MyThread implements Runnable{//執行緒的主體類
	private String title;
	public MyThread(String title) {
		this.title = title;
	}
	@Override
	public void run() {
		for(int x = 0;x < 10;x++) {
			System.out.println(this.title + "執行,x = " + x); 
		}
	}
}

 結果:

多執行緒C執行,x = 0
多執行緒A執行,x = 0
多執行緒B執行,x = 0
多執行緒A執行,x = 1
多執行緒C執行,x = 1
多執行緒A執行,x = 2
多執行緒B執行,x = 1
多執行緒B執行,x = 2
多執行緒B執行,x = 3
多執行緒B執行,x = 4
多執行緒B執行,x = 5
多執行緒B執行,x = 6
多執行緒B執行,x = 7
多執行緒B執行,x = 8
多執行緒B執行,x = 9
多執行緒A執行,x = 3
多執行緒A執行,x = 4
多執行緒A執行,x = 5
多執行緒A執行,x = 6
多執行緒A執行,x = 7
多執行緒A執行,x = 8
多執行緒A執行,x = 9
多執行緒C執行,x = 2
多執行緒C執行,x = 3
多執行緒C執行,x = 4
多執行緒C執行,x = 5
多執行緒C執行,x = 6
多執行緒C執行,x = 7
多執行緒C執行,x = 8
多執行緒C執行,x = 9

這個時候的多執行緒實現,由於只是實現了Runnable的介面物件,所以此時執行緒主體類上不再有單繼承的侷限,這樣的設計才是一個標註性的設計。

可以發現從JDK1.8開始,Runnable介面使用了函式式介面的定義,所以也可以利用Lambda表示式進行執行緒類實現。

範例:利用Lambda實現定義

package cn.mldn.demo;

public class ThreadDemo {
	public static void main(String[] args) {
		for(int x = 0;x < 3;x++) {
			String title = "執行緒物件-"+x;
			
			new Thread(()->{	//新建一個Thread物件構造方法直接填寫Lambda表示式
				for(int y = 0;y < 10;y++) {
					System.out.println(title + "執行,y = " + y); 
				}
			}).start();
		}
	}
}

結果:

執行緒物件-0執行,y = 0
執行緒物件-1執行,y = 0
執行緒物件-1執行,y = 1
執行緒物件-1執行,y = 2
執行緒物件-2執行,y = 0
執行緒物件-1執行,y = 3
執行緒物件-2執行,y = 1
執行緒物件-1執行,y = 4
執行緒物件-1執行,y = 5
執行緒物件-1執行,y = 6
執行緒物件-1執行,y = 7
執行緒物件-1執行,y = 8
執行緒物件-1執行,y = 9
執行緒物件-2執行,y = 2
執行緒物件-2執行,y = 3
執行緒物件-2執行,y = 4
執行緒物件-2執行,y = 5
執行緒物件-2執行,y = 6
執行緒物件-2執行,y = 7
執行緒物件-2執行,y = 8
執行緒物件-2執行,y = 9
執行緒物件-0執行,y = 1
執行緒物件-0執行,y = 2
執行緒物件-0執行,y = 3
執行緒物件-0執行,y = 4
執行緒物件-0執行,y = 5
執行緒物件-0執行,y = 6
執行緒物件-0執行,y = 7
執行緒物件-0執行,y = 8
執行緒物件-0執行,y = 9

在以後的開發之中優先考慮的就是Runnable介面實現,並且永恆都是通過Thread類物件啟動執行緒。

相關文章