pla*_*ino 2 java concurrency deadlock executorservice threadpool
我在ThreadPoolExecutor中运行任务时发现了意外的死锁.
这个想法是一个主要任务,它启动一个改变标志的次要任务.主任务暂停,直到辅助任务更新标志.
我想知道:
corePoolSize = 2是一个安全值来防止这种死锁吗?
import java.util.concurrent.*;
class ExecutorDeadlock {
/*------ FIELDS -------------*/
boolean halted = true;
ExecutorService executor;
Runnable secondaryTask = new Runnable() {
public void run() {
System.out.println("secondaryTask started");
halted = false;
System.out.println("secondaryTask completed");
}
};
Runnable primaryTask = new Runnable() {
public void run() {
System.out.println("primaryTask started");
executor.execute(secondaryTask);
while (halted) {
try {
Thread.sleep(500);
}
catch (Throwable e) {
e.printStackTrace();
}
}
System.out.println("primaryTask completed");
}
};
/*-------- EXECUTE -----------*/
void execute(){
executor.execute(primaryTask);
}
/*-------- CTOR -----------*/
ExecutorDeadlock(int corePoolSize,BlockingQueue<Runnable> workQueue) {
this.executor = new ThreadPoolExecutor(corePoolSize, 4,0L, TimeUnit.MILLISECONDS, workQueue);
}
/*-------- TEST -----------*/
public static void main(String[] args) {
new ExecutorDeadlock(2,new LinkedBlockingQueue<>()).execute();
//new ExecutorDeadlock(1,new LinkedBlockingQueue<>()).execute();
//new ExecutorDeadlock(0,new SynchronousQueue<>()).execute();
}
}
Run Code Online (Sandbox Code Playgroud)你如何期望这个线程计数<2如果
当池中有可用执行程序时,执行程序服务从队列中获取任务.在你的情况下(<2)执行程序线程永远不会被第一个任务释放.这里没有死锁问题.
编辑:
好的,我挖出了一些信息,这就是我发现的.首先来自的一些信息ThreadPoolExecutor
任何BlockingQueue都可用于传输和保存提交的任务.此队列的使用与池大小调整交互:
Run Code Online (Sandbox Code Playgroud)If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing. If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread. If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.
好的,现在和queuess offer方法一样
SyncQueue:
如果另一个线程正在等待接收它,则将指定的元素插入此队列.
的LinkedBlockingQueue
将指定的元素插入此队列,等待空间变为可用.
offer方法的返回值确定新任务将在新线程中排队或运行.
由于LinkedBlockingQueue它可以因为它具有容量而被排队,因此任务被排队并且不会产生新的线程.但是SyncQueu不会排队另一个任务,因为没有其他线程正在等待某些事情被排队(offer因为任务没有入队而返回false),这就是为什么会产生新的执行程序线程.
如果您阅读javadocs ThreadPoolExecutor LinkedBlockingQueue和SynchronousQueue+检查execute方法的实现,您将得出相同的结论.
所以你错了,文档中有explenation :)
| 归档时间: |
|
| 查看次数: |
779 次 |
| 最近记录: |