我有一个固定线程池的
我在另一个线程上调用该列表的
完整源代码:(由于并发可能需要运行多次)
ExecutorService
,宽度为10,并且有一个包含100个Callable
的列表,每个Callable
等待20秒并记录它们的中断。我在另一个线程上调用该列表的
invokeAll
方法,并几乎立即中断该线程。如预期,ExecutorService
的执行被中断,但是Callable
实际记录到的中断次数远远超过了预期的10次 - 大约是20-40次。如果ExecutorService
无法同时执行超过10个线程,那么为什么会这样呢?完整源代码:(由于并发可能需要运行多次)
@Test
public void interrupt3() throws Exception{
int callableNum = 100;
int executorThreadNum = 10;
final AtomicInteger interruptCounter = new AtomicInteger(0);
final ExecutorService executorService = Executors.newFixedThreadPool(executorThreadNum);
final List <Callable <Object>> executeds = new ArrayList <Callable <Object>>();
for (int i = 0; i < callableNum; ++i) {
executeds.add(new Waiter(interruptCounter));
}
Thread watcher = new Thread(new Runnable() {
@Override
public void run(){
try {
executorService.invokeAll(executeds);
} catch(InterruptedException ex) {
// NOOP
}
}
});
watcher.start();
Thread.sleep(200);
watcher.interrupt();
Thread.sleep(200);
assertEquals(10, interruptCounter.get());
}
// This class just waits for 20 seconds, recording it's interrupts
private class Waiter implements Callable <Object> {
private AtomicInteger interruptCounter;
public Waiter(AtomicInteger interruptCounter){
this.interruptCounter = interruptCounter;
}
@Override
public Object call() throws Exception{
try {
Thread.sleep(20000);
} catch(InterruptedException ex) {
interruptCounter.getAndIncrement();
}
return null;
}
}
使用WinXP 32位操作系统,Oracle JRE 1.6.0_27和JUnit4。