11.互聯網大廠高頻面試題-阻塞隊列(下)+callable介紹

生產者消費者-阻塞隊列版本

在這裏插入圖片描述
關於上面的代碼,多線程環境下,調用資源類,關鍵變量要加volatile,原子類變量不用加,因爲源碼裏面的包裝類加了,我們在這裏使用就不用加。如果是想做適配性很好的代碼設計,要適配所有的阻塞隊列的子類,就不能在方法裏確定,而是要讓調用者把具體的實現傳進來,也就是面向接口的編程。所謂的高手都是傳接口,絕對不是傳類!
關於這裏的代碼,寫,要足夠的抽象,也就是傳接口,要查,要利用反射,把具體的類的實現記一下日誌。
在這裏插入圖片描述
在這裏插入圖片描述
這個地方消費線程flag=false的行爲,我不是很認同,消費線程取不到不應該停下吧,個人認爲這個邏輯不對。
在這裏插入圖片描述
測試代碼:
在這裏插入圖片描述
5s後叫停。
在這裏插入圖片描述

執行結果:
在這裏插入圖片描述

總結一下阻塞隊列版本的線程通信:
在這裏插入圖片描述

Callable接口

多線程的方式:
在這裏插入圖片描述
兩者的區別:1.runable接口沒有返回值。但另一個是有的(適用於帶返回值的線程工作流)。2.接口實現方法不一樣,一個run,一個call、3
那麼callable接口怎麼在項目中使用呢?如果只用thread去接收callable接口該如何處理呢?目前thread只能接受runable接口。
在這裏插入圖片描述
如果一個類即實現了runable,也實現了callable,傳這一個類就可以變相的適配了,這就是適配器模式的使用。
JDK給我們提供了,他就是futureTask接口。本身是runable接口的子類,傳進去callable接口,就可以實現適配了。
在這裏插入圖片描述
實際使用:
在這裏插入圖片描述
在這裏插入圖片描述
運行結果:
在這裏插入圖片描述
如何獲得callable的返回值呢?api提供了,如下:
在這裏插入圖片描述
這種用法在批次任務中,經常會出現。比如每一筆帳都要有返回值。
爲什麼callable會出現:併發,異步,導致callable出來了。
以前沒有callable,編程的感覺就是一根籤子通到底,冰糖葫蘆串,順序執行。如果節點佔用時間過長,那就只能等着。
但是有了多線程之後,就可以用callable接口,把可以拆分的任務拆分出去並行執行,最後結果彙總。
多線程牛逼的不是鎖,而是控制.
技巧:futureTask的get方法,建議放在最後執行。因爲一旦get的那個任務還沒執行完成,那麼就會阻塞在這,所以get方法一般放在最後。
那麼什麼時候彙總呢?可以用自旋鎖的思想,while一直去主動確認。
在這裏插入圖片描述

問題:如果一個futureTask被兩個線程執行了2次,那麼相關方法會如何執行?
結果是,只會執行一遍,因爲一個計算過程算一遍就對了,不會算兩遍。
在這裏插入圖片描述
總結:多個線程搶一個futureTask只算一次。要想多算,要有多個futureTask。
以上就是我們第三種獲得線程的方式。runable,callable,futureTask。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章