《Java併發程式設計實戰》筆記2 取消與關閉

2021-08-28 03:16:14 字數 2431 閱讀 9016

1、取消

(1)生產者消費者問題中,如果採用blockingqueue阻塞佇列。假如生產者生產的速度超過了消費者的處理速度,佇列將被填滿,put操作也會被阻塞。當生產者在put方法中阻塞時,如果消費者希望取消生產者任務,它可以通過呼叫cancel方法來設定cancelled標誌,但此時生產者卻永遠不能檢查這個標誌,因為它無法從阻塞的方法中恢復過來(消費者已經停止從佇列中取出素數,所以put方法將一直保持阻塞狀態)。此時任務永遠不會結束。

如下面**:

public class brokenprimeproducer extends thread 

public void run()

}system.out.println("!!結束!!");

} catch (interruptedexception e)

} public void cancel()

static void consumeprimes() throws interruptedexception

try

} finally

} private static void consume(biginteger take)

private static boolean needmoreprimes()

return false;

} public static void main(string args) throws interruptedexception

}

執行結果:

(2)中斷取消

在上面示例中,幸運的話有可能會取消,但多數情況是沒有辦法檢測到cancelled標誌,一直阻塞。可以採用中斷的方法取消。

thread的中斷方法有:

public class thread//中斷執行緒

public static boolean interrupted(){}//清除中斷狀態

public boolean isinterrupted(){}

}

中斷並不會真正地中斷乙個正在執行的執行緒,而只是發出中斷請求,然後由執行緒在下乙個合適的時刻中斷自己。 

將示例**做出改動:

public void run() 

}} catch (interruptedexception e)

} public void cancel()

static void consumeprimes() throws interruptedexception

try

} finally

} }

結果:

在每次迭代迴圈中有兩個地方可以檢測出中斷,乙個是put方法呼叫,乙個是迴圈開始處查詢狀態時。

在取消過程中可能涉及除了中斷狀態之外的其他狀態,,中斷可以用來獲得執行緒的注意,並且由中斷執行緒儲存的資訊,可以為中斷的執行緒提供進一步的指示。(當訪問這些資訊時,要保證使用同步)

例如,當乙個threadpoolexecutor擁有的工作者執行緒檢測到中斷時,它會檢查執行緒池是否正在關閉。如果是,它會在結束之前執行一些執行緒池清理工作,否則它可能建立乙個新執行緒將執行緒池恢復到合理的規模。

(4)計時執行

這是一種簡單的方法,但卻破壞了一下規則:在中斷執行緒之前,應該了解它的中斷策略。由於timedrun可以從任意乙個執行緒呼叫,因此無法知道這個呼叫執行緒的中斷策略。我的理解是,因為這個方法不知道呼叫的方法後續的處理,所以如果捕獲異常,應該拋回去給呼叫方處理。改進如下:

(6)可以根據自己的需求來重寫中斷方法

2、關閉

(1)中斷。當取消乙個生產者-消費者操作時需要同時取消生產者和消費者。

(2)設定「請求關閉」標誌

(3)使用executorservice

(4)「毒丸」物件。「poison pill」是指乙個放在佇列上的物件,當得到這個物件時,立即停止。在fifo佇列中,「poison pill」將確保消費者在關閉之前首先完成佇列中的所有工作,在提交「毒丸」物件之前提交的所有工作都會被處理,而生產者在提交了「毒丸」物件後,將不會再提交任何工作。

注:只有生產者和消費者數量已知的情況下才可以使用毒丸物件。

Java併發 JAVA併發程式設計實戰 讀書筆記3

發布乙個物件的意思是使它能夠被當前範圍之外的 所使用。比如將乙個引用儲存到其他 可以訪問的地方,在乙個非私有的方法中返回這個引用。在很多情況下,我們需要確保物件及它們的內部狀態不被暴露。乙個物件在尚未準備好時就將它發布,稱作逸出。最常見的發布物件的方式就是將物件的引用儲存到公共靜態域中,任何類和執行...

Java併發 JAVA併發程式設計實戰 讀書筆記8

為計算結果建立高效 可伸縮的快取記憶體 public inte ce computable public class expensivefunction implements computable public class memoizer1implements computable public ...

Java併發 JAVA併發程式設計實戰 讀書筆記14

無論何時,執行緒池需要建立乙個執行緒都要通過乙個執行緒工廠。public inte ce threadfactory 預設的執行緒工廠建立乙個新的非守護的執行緒,其中的newthread 會在建立乙個新執行緒時被呼叫。public class mythreadfactory implements t...