У меня есть фиксированный пул потоков ExecutorService
шириной 10 и список из 100 Callable
, каждый ждут 20 секунд и записывают свои прерывания.
Я вызываю invokeAll
в этом списке в отдельном потоке и почти сразу прерываю этот поток. Выполнение ExecutorService
прервано, как и ожидалось, но фактическое количество прерываний, записанных Callable
s, намного больше, чем ожидалось 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;
}
}
Использование 32-разрядной версии WinXP , Oracle JRE 1.6.0_27 и JUnit4