在線程間通信時遇到問題,並通過在整個地方使用「虛擬消息」來「解決」它。這是一個壞主意嗎?有什麼解決方法?生產者 - 消費者線程間通信
示例我有問題。
主線程啓動一個處理線程並將記錄插入到數據庫中。 主線程讀取一個可能很大的文件,並將一個記錄(對象)放入另一個記錄(對象)中。處理線程從隊列中讀取並確實工作。
如何告訴「處理線程」停止? 隊列可以是空的,但工作沒有完成,並且主線程現在不會在處理線程完成工作並且不能中斷它時。
所以處理線程做
while (queue.size() > 0 || !Thread.currentThread().isInterrupted()) {
MyObject object= queue.poll(100, TimeUnit.MILLISECONDS);
if (object != null) {
String data = object.getData();
if (data.equals("END")) {
break;
}
// do work
}
}
// clean-up
synchronized queue) {
queue.notifyAll();
}
return;
和主線程
// ...start processing thread...
while(reader.hasNext(){
// ...read whole file and put data in queue...
}
MyObject dummy = new MyObject();
dummy.setData("END");
queue.put(dummy);
//Note: empty queue here means work is done
while (queue.size() > 0) {
synchronized (queue) {
queue.wait(500); // over-cautios locking prevention i guess
}
}
注意,插入必須在同一個事務和事務不能由主線程來處理 。
這樣做會更好嗎? (我正在學習,不想以「錯誤的方式開始」)
好的。如果傳遞的對象的類型沒有可以輕易用於此的String字段,我將如何使用它?如果任何文本可能是有效的數據,因此可能等於毒藥?使用GUID? – 2011-12-22 14:01:28
理想情況下,您可以更改MyObject類並在其中添加isPoison()方法。這種方法如何確定對象是否是毒藥取決於你,可能是一個簡單的事情,比如比較消息是否爲空,或者消息是否明確創建爲毒藥。一個想法是將MyObject重構爲兩個實現的接口,一個始終在isPoison()方法中返回false的MessageObject和一個始終返回true的PoisonMessage。但是,這很大程度上取決於你在做什麼,根據你的真實情況可能會有更好的解決方案。 – 2011-12-22 14:08:54