这是我第一次使用线程池,我不太了解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();
线程不等到一个线程完成吗?
答案 0 :(得分:0)
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的ctl
值提供的顺序。 ctl
是AtomicInteger
内部存储的全局池状态(用于获取非阻塞原子ThreadPoolExecutor
状态)。
因此,以下情况是可能的。
getTask
的工作线程RUNNING
。ctl
。