Skip to content

Instantly share code, notes, and snippets.

@yuzd
Created December 1, 2022 10:32
Show Gist options
  • Save yuzd/ab3f4940058bc74dc4527ff03aa70b78 to your computer and use it in GitHub Desktop.
Save yuzd/ab3f4940058bc74dc4527ff03aa70b78 to your computer and use it in GitHub Desktop.
共用threadpool导致死锁问题
import java.util.concurrent.*;
import java.util.stream.IntStream;
/**
* @author yuzd
* @date 2022/12/1 16:24
*/
public class PoolTest {
// 模拟nio线程池
static ThreadPoolExecutor nioExecutor = new ThreadPoolExecutor(20, 20, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),
new CustomerNamedThreadFactory("nio", false),
new ThreadPoolExecutor.AbortPolicy());
// 业务线程池
static ThreadPoolExecutor buExecutor = new ThreadPoolExecutor(20, 20, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),
new CustomerNamedThreadFactory("bu", true),
new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
// 模拟是http请求并发20个
IntStream.rangeClosed(1, 20).parallel().forEach((index) -> {
// 交给nio线程池处理
nioExecutor.execute(() -> {
try {
httpHandler(index);
} catch (Exception e) {
e.printStackTrace();
}
});
});
}
static void httpHandler(int index) throws ExecutionException, InterruptedException {
System.out.println(Thread.currentThread().getName() + " request index :" + index + " staring");
// 交给业务线程池处理
Future<String> parentFuture = buExecutor.submit(() -> process1(index));
String p1Rt = parentFuture.get(); // nio线程在wait
System.out.println(Thread.currentThread().getName() + " request index :" + p1Rt + " ending");
}
// future1
static String process1(int index) throws ExecutionException, InterruptedException {
System.out.println( Thread.currentThread().getName() + " process1 index :" + index + " staring");
Future<String> childFuture = buExecutor.submit(() -> process2(index));
String p2Rt = childFuture.get(); // 这里是bu线程在wait 这里会发生死锁
System.out.println(Thread.currentThread().getName() + " process1 index :" + index + " ending");
return p2Rt;
}
// future2
static String process2(int index) throws InterruptedException, ExecutionException {
System.out.println(Thread.currentThread().getName() + " process2 index :" + index + " staring");
// 加上就会死锁
// 只要不一下子产生足够数量的task(把core全部占掉)就不会死锁 加了这里就会把core全部占据 导致task进入到queue,core线程在wait future.get 无法被释放, 而queue的任务在等待它释放产生新的线程
Future<String> submit = buExecutor.submit(() -> {
try {
Thread.sleep(1000);
return String.valueOf(index);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
submit.get();
System.out.println(Thread.currentThread().getName() + " process2 index :" + index + " ending");
return String.valueOf(index);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment