[英]Synchronization Thread Pool ExecutorService
這是我第一次使用線程池,我不太了解executorservice的工作方式。 我將水印放在圖像上,然后將它們合並到一張空白圖片上。 但是即使我只使用一個線程,它也只會畫一半。
這是我的WorkerThread類 :
public class WorkerThread implements Runnable {
BufferedImage source;
BufferedImage toDraw;
int x;
int y;
BufferedImage target;
ParallelWatermarkFilter pf;
public WorkerThread(BufferedImage source, BufferedImage toDraw, int x, int y, BufferedImage target){
this.source = source;
this.toDraw = toDraw;
this.x = x;
this.y = y;
this.target = target;
pf = new ParallelWatermarkFilter(source, 5);
}
@Override
public void run() {
pf.mergeImages(source, toDraw, x, y, target);
}
}
這就是我在FilterClass中使用ExecutorService的方式 :
public BufferedImage apply(BufferedImage input) {
ExecutorService threadpool = Executors.newFixedThreadPool(numThreads);
for (int w = 0; w < imgWidth; w += watermarkWidth) {
for (int h = 0; h < imgHeight; h += watermarkHeight) {
Runnable worker = new WorkerThread(input, watermark, w, h, result);
System.out.println("WIDTH: " + w + " HEIGHT: " + h);
threadpool.execute(worker);
}
}
threadpool.shutdown();
線程是否不等到一個線程完成?
ThreadPoolExecutor
關機和任務執行/排空工作隊列/從工作隊列中取出是一件ThreadPoolExecutor
的事。 因此,您不能依賴線程中斷機制或其他方法。 您所能保證的是:
啟動有序關閉,在該關閉中執行先前提交的任務,但不接受任何新任務。 如果已關閉,則調用不會產生任何其他影響。
此方法不等待先前提交的任務完成執行。
為了更深入地了解ThreadPoolExecutor
實現,讓我們看一下主要的執行方法:
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
這里的關鍵部分是調用getTask()
。 其片段是:
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
該方法不同步,僅依靠CAS'ed ctl
值提供的排序。 這里的ctl
是存儲在AtomicInteger
內部的全局池狀態(用於非阻塞原子ThreadPoolExecutor
狀態獲取)。
因此,以下情況是可能的。
getTask
工作線程 RUNNING
。 ctl
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.