我有一個ScheduledThreadPoolExecutor
與4個活動線程。它充滿了大量的任務,每個任務處理一大堆項目。使用一個Java 8 Consumer作爲Runnable回調 - 是線程安全的嗎?
每個任務必須有3個回調:每個處理的項目後有開始,結束和一個回調。
每個回調都會在我的數據庫中觸發更新。這是一個有點長時間運行的任務。
下面是一段示例代碼,這應該說明我在做什麼:
public static void main(String[] args) throws InterruptedException {
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(4);
Consumer<String> processed = (String o) -> {
System.err.println("PROCESSED: " + o);
try { Thread.sleep(10); }
catch (Exception e) { e.printStackTrace(); }
};
for(int i=0; i<10; i++) {
executor.schedule(
new ChunkTask("task"+i, processed),
500,
TimeUnit.MILLISECONDS
);
}
}
public static class ChunkTask implements Runnable {
String taskId;
Consumer<String> processedCallback;
public ChunkTask(String taskId, Consumer<String> processedCallback) {
this.taskId = taskId;
this.processedCallback = processedCallback;
}
@Override
public void run() {
for(int i=0; i<50; i++) {
processedCallback.accept(taskId+" "+i);
}
}
}
我只是省略了開始和結束回調,因爲它基本上是一樣的處理回調。
正如您所看到的,我創建了一個Consumer
對象。其中有一個Thread.sleep(10)
來模擬數據庫訪問。這個對象被所有4個線程並行調用。
我不知道這是否是線程安全的。 在我看來,,Consumer
只是一個無狀態的對象,具有無狀態的方法。儘管可以多次並行調用它。
我對不對?
編輯:我知道我的回調是同步的。這只是爲了測試。後來我想讓它成爲異步。
線程安全是一個複雜的問題。建議您閱讀_Java併發實踐_... – 2015-04-03 19:09:03