1. 程式人生 > 其它 >java高階(十五)——多執行緒

java高階(十五)——多執行緒

技術標籤:Java基礎java多執行緒

java高階部分多執行緒

建立執行緒的方式

方式一:繼承Thread類

1.建立一個類繼承Thread類
2.在子類中重寫Thread類的run()方法
3.建立子類物件
4.通過子類物件呼叫start()方法 (start方法的作用:①啟動執行緒②呼叫當前執行緒的run方法)

方式二:實現Runnable介面(建議用這種)

1.建立一個類實現Runnable介面
2.實現類中實現介面的抽象方法
3.建立介面的實現類物件

4.將這個物件作為引數傳入Thread類的構造器中,建立Thread類的物件
5.通過Thread類的物件呼叫start()方法

方式一和方式二兩種方式的比較

聯絡
Thread類底層也是實現的Runnable介面
都需要重寫run方法

方式三:實現Callable介面(jdk1.5後新增)相比方式二更加強大

具體步驟:
1.建立一個類實現Callable介面
2.實現Callable介面中的call()方法
3.編寫執行緒具體操作程式碼
4.建立Callable介面的實現類物件
5.將Callable介面的實現類物件傳入FutureTask類的構造器中,
建立FutureTask類的物件
6.將FutureTask類的物件作為引數傳入Thread類的構造器中,

建立Thread類的物件,並呼叫start()方法

相比實現Runnable介面這種方式,實現Callable的方式有什麼強大之處?

1.call()方法中可以擁有返回值
2.該方式中可以處理異常
3.該方式中可以使用泛型

方式四:執行緒池

步驟
		1.建立執行緒池大小  
					        ExecutorService service = Executors.newFixedThreadPool(10);
		2.執行執行緒
					// execute       適用於實現Runnable介面
        service.execute(new Runnable() {...}
					// submit      適用於實現Callable介面
        service.submit(new Callable<Object>() {...}
		3.關閉執行緒池
		service.shutdown();

執行緒 生命週期

新建
就緒
執行
阻塞
死亡
在這裡插入圖片描述

執行緒的同步

執行緒的安全問題

當一個執行緒在執行時,遇到了阻塞,這時另一個執行緒參與了進來,也進行操作,就會造成執行緒安全問題(如賣票)

如何解決

方式一:同步程式碼塊

synchronize(同步監視器){程式碼:操作共享資料的程式碼}

同步監視器(通俗講就叫鎖)

任何一個類的物件,都可以充當鎖(要求:多個執行緒必須共用同一把鎖)
也可以使用this代表當前物件,但是隻能在建立一個物件的情況下使用(思考)

缺點

操作同步程式碼塊時,只能有一個執行緒參與,其他執行緒需要等待,就相當於一個單執行緒了

方式二:同步方法

在建立方法時使用synchronized

使用實現Runnable介面的方式

只需要建立一個實現類的物件,因此可以直接使用synchronized修飾run()方法
此時,同步監聽器為:this

使用繼承Thread的方式

因為會建立多個子類的物件,直接使用synchronized修飾run方法不起作用,還需將這個方法使用static關鍵字修飾
此時,同步監聽器就變為:當前類本身

方式三:Lock鎖

java.util.concurrent.locks.Lock介面是控制多個執行緒對共享資源訪問的工具。
使用同步鎖:建立Lock介面的實現類ReentrantLock的物件
通過物件呼叫鎖定方法lock()/解鎖方法unlock()

synchronized與lock鎖的異同

相同點

都是解決執行緒的同步安全問題

區別

synchronized同步方法/程式碼塊的方式,每次執行完程式碼後自動解鎖
而lock鎖的方式需要手動鎖定、手動解鎖

執行緒的死鎖

		不同的執行緒互相佔用了對方的資源不放棄,都在等待對方釋放,就形成了執行緒的死鎖(如兩個人吃飯,只有一雙筷子,都在等待對方將另一隻筷子給自己)

解決死鎖

		演算法、減少同步資源的定義、避免巢狀同步資源

執行緒的通訊

wait()方法

當前執行緒進去阻塞狀態

notify()方法

喚醒被wait的一個執行緒(如果有多個執行緒被wait),喚醒優先順序較高的

notifyAll()方法

喚醒所有被wait的執行緒
這3個方法必須放在synchronized程式碼塊中,這三個方法的呼叫中必須是同步程式碼塊或同步方法的同步監視器

sleep()和wait()方法的區別

相同點
都可以讓當前執行緒進入阻塞狀態
不同點

1.宣告的位置:

		sleep方法在Thread類中
		wait方法在Object類中

2.呼叫位置

		sleep方法可以在任何需要的地方呼叫
		wait方法必須在同步程式碼塊/同步方法中

3.是否釋放同步監視器

		sleep方法不釋放
		wait方法釋放同步監視器