Created
December 1, 2022 10:32
-
-
Save yuzd/ab3f4940058bc74dc4527ff03aa70b78 to your computer and use it in GitHub Desktop.
共用threadpool导致死锁问题
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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