我有一个示例代码。
@Test
public void testWithBlockQueue() throws InterruptedException {
String poolFormat = "ServiceTaskPool-%d";
int coreSize = 3;
int maxSize = 3;
int queueSize = 1;
int idleThreadLiveInSecond = 35;
ThreadFactory factory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
};
ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(queueSize);
final ThreadPoolExecutor service = new ThreadPoolExecutor(coreSize, maxSize, idleThreadLiveInSecond,
TimeUnit.SECONDS, queue, factory, new ThreadPoolExecutor.AbortPolicy());
service.allowCoreThreadTimeOut(true);
passTask(coreSize, service);
Thread.sleep(5000);
passTask(coreSize, service);
System.out.printf("Thread pool state %s", service);
Thread.sleep(6000);
}
protected void passTask(int coreSize, ThreadPoolExecutor service) {
for (int i=0; i < coreSize; i++) {
service.execute(new Runnable() {
@Override
public void run() {
System.out.printf("Simple printf from %s \n", Thread.currentThread().getName());
}
});
}
}
当我设置queueSize 2时,我得到了异常,因为threadpool执行器不能插入一个任务到队列中,当我设置queueSize 3时是可以的。我不明白为什么当我设置maxSize=4时,测试是可以的。它来自留档。
事实上,当maxSize=4时,可能会引发异常
第一次调用passTask(coreSize,service),我们得到task1、task2、task3。将创建thread1、thread2、thread3来运行它们。
第二次调用passTask(coreSize,service):
>
2.1. 如果task4仍在队列中,则将创建thread4并运行task5;
2.2. 如果线程1、线程2或线程3已从队列中获取task4,则task5将被放入队列中。
i=2, whe get task6.
3.1. 如果task4仍在队列中,则必须有4个活动线程,并且由于队列已满,将引发异常;
3.2. 如果task5在队列中,则必须有三个线程处于活动状态,因此将创建thread4并运行task6;
3.3. 如果队列为空,则将task6放入队列中。
在条件3.1下,可以抛出异常。但是在测试中,任务会很快从块队列中取出,所以这种情况很少发生。
附笔。:
当maxSize=3且queueSize=1时,添加此行
<代码>线程。睡眠(10)
之后
<代码>用于(int i=0;i
可以使您的代码在没有异常的情况下运行。