[英]How to use the method “removeIf” using a Predicate in a ArrayBlockingQueue
我有以下課程:
WorkerTask.java
public interface WorkerTask extends Task {
// Constants
public static final short WORKERTASK_SPIDER = 1;
public static final short WORKERTASK_PARSER = 2;
public static final short WORKERTASK_PRODUCT = 3;
public int getType();
}
WorkerPool.java
class workerPool {
private ThreadPoolExecutor executorPool_;
//----------------------------------------------------
public WorkerPool(int poolSize)
{
executorPool_ = new ThreadPoolExecutor(
poolSize,5,10,TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10000000,false),
Executors.defaultThreadFactory()
);
//----------------------------------------------------
public void assign(WorkerTask workerTask) {
executorPool_.execute(new WorkerThread(workerTask));
}
//----------------------------------------------------
public void removeTasks(int siteID) {
executorPool_.getQueue().removeIf(...);
}
}
我想調用方法removeTasks來刪除一定數量的掛起任務,但我不知道如何使用方法removeIf。 它說:刪除此集合中滿足給定謂詞的所有元素,但我不知道如何創建參數Predicate。 任何的想法?
如果你有一個Queue<WorkerTask>
,你可以這樣做:
queue.removeIf(task -> task.getSiteID() == siteID)
有幾個問題。 一個問題是你從getQueue()
獲得的隊列是BlockingQueue<Runnable>
而不是Queue<WorkerTask>
。 如果要將Runnable
實例提交到池中,則隊列可能包含對實際任務的引用; 如果是這樣,你可以將它們WorkerTask
給WorkerTask
。 但是,這不能保證。 此外, ThreadPoolExecutor的類doc說(在“隊列維護”下):
方法
getQueue()
允許訪問工作隊列以進行監視和調試。 強烈建議不要將此方法用於任何其他目的。 當大量排隊的任務被取消時,兩個提供的方法remove(Runnable)
和purge()
可用於協助存儲回收。
查看remove(Runnable)
方法,其文檔說
在放入內部隊列之前,它可能無法刪除已轉換為其他表單的任務。
這表明您應該掛起已提交的Runnable
實例,以便稍后調用remove()
。 或者,調用submit(Runnable)
獲取Future
並保存這些實例以取消它們。
但是還有第二個問題可能導致這種方法不足。 假設您已找到一種方法從隊列中刪除或取消匹配的任務。 另一個線程可能已決定提交匹配的新任務,但尚未提交。 這里有競爭條件。 您可以取消已排隊的任務,但在完成之后,您無法保證尚未提交新的匹配任務。
這是另一種方法。 據推測,當你取消(或者不管)某個站點ID時,有一些邏輯可以停止提交與該ID相匹配的新任務。 問題是如何處理“在飛行中”的匹配任務,即隊列中或即將入隊的任務。
不要嘗試取消匹配的任務,而是更改任務,以便在其網站ID被取消后,任務變為無操作。 您可以在ConcurrentHashMap
記錄網站ID的取消。 任何任務都會在開始工作之前檢查此地圖,如果網站ID存在,則只返回。 向站點添加站點ID將立即生效,確保不會開始該站點ID上的新任務。 (已經啟動的任務將運行完成。)任何正在進行的任務最終將從隊列中排出,而不會導致任何實際工作發生。
謂詞是一個接收輸入並返回布爾值的函數。
如果您使用的是java 8,則可以使用lambda表達式: (elem) -> return elem.id == siteID
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.