1.初識java多線程《java編程思想筆記》

代碼來自《java編程思想》

任務:

我們使用多線程,去執行的都是任務,那麼我們首先得學會如何定義一個任務。

public class LiftOff implements Runnable{
	
	protected int countDown = 10;
	private static int taskCount = 0;
	private final int id = taskCount++;
	public LiftOff(){}
	public LiftOff(int countDown)
	{
		this.countDown = countDown;		
	}
	public String status(){
		
		return "#"+id+"("+(countDown>0?countDown:"liftOff!")+"),";
	}
	public void run(){
		while(countDown-->0)
			System.out.println(status());
			Thread.yield();		
	}

}
這個任務類,實現了Runnable接口,然後覆蓋run()方法。這兩點是必須的。

如果,我們在main方法裏面,調用這個run方法,比如

        public static void main(String args[]){
		LiftOff launch = new LiftOff();
		launch.run();		
		
	}
會輸出:

#0(9),
#0(8),
#0(7),
#0(6),
#0(5),
#0(4),
#0(3),
#0(2),
#0(1),
#0(liftOff!),
其實這裏雖然我們執行了一個任務(launch 實現了Runnable接口),但是這也不是我們今天要看的多線程。他就像一個普通的調用方法一樣在執行。整個執行過程中,只有main()一個線程,run()方法在main線程中執行。

那麼我們怎麼將這個任務變成多線程執行呢。

Thread類

那麼我們怎麼將這個任務變成多線程執行呢?將他交給Thread構造器。

public static void main(String args[]){

		Thread t = new Thread(new LiftOff());
		t.start();
		System.out.println("wait for liftoff");
	}
輸出:

wait for liftoff
#0(9),
#0(8),
#0(7),
#0(6),
#0(5),
#0(4),
#0(3),
#0(2),
#0(1),
#0(liftOff!),
如果我們沒有多線程的概念,還是停留在順序執行的思維中。會不會比較奇怪System.out.println("wait for liftoff");竟然在t.start()方法前面執行!

實際上Thread t = new Thread(new LiftOff());  t.start();這兩句是產生一個新的線程,然後去執行任務的run()方法。

這裏,我們就有了兩個線程,一個main函數的線程,一個run()方法的線程。那麼至於main()函數中之後的操作和run()方法以什麼樣子的順序執行。這個只能有線程調用器自動控制了。


main()中多幾個線程,我們看看究竟怎麼執行的

public static void main(String args[]){
		for(int i=0;i<5;i++){			
			new Thread(new LiftOff()).start();
		}		
		System.out.println("wait for liftoff");
	}

這個程序執行多次,輸出是不一樣的。挑了一個比較亂的順序大家感受下

wait for liftoff
#2(9),
#3(9),
#4(9),
#1(9),
#2(8),
#1(8),
#4(8),
#0(9),
#3(8),
#0(8),
#4(7),
#1(7),
#2(7),
#1(6),
#4(6),
#4(5),
#0(7),
#3(7),
#0(6),
#4(4),
#1(5),
#2(6),
#1(4),
#4(3),
#0(5),
#3(6),
#0(4),
#4(2),
#1(3),
#2(5),
#1(2),
#4(1),
#0(3),
#3(5),
#0(2),
#4(liftOff!),
#1(1),
#2(4),
#1(liftOff!),
#0(1),
#0(liftOff!),
#3(4),
#2(3),
#3(3),
#2(2),
#3(2),
#2(1),
#3(1),
#2(liftOff!),
#3(liftOff!),


補充:從任務中返回值

實現了Runnable接口,覆蓋了run方法不會返回任何值,如果希望每個任務返回一個值。那就可以實現Callable接口,覆蓋call()方法。但是,必須使用ExecutorService.sunmit()方法調用他。ExecutorService.sunmit()用法見第二篇文章


發佈了27 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章