newFixedThreadPool 介绍
- 线程执行完不会结束
- 核心线程数 == 最大线程数(没有救急线程被创建),因此也无需超时时间
- 阻塞队列是无界的,可以放任意数量的任务
评价 适用于任务量已知,相对耗时的任务
饥饿问题引出
餐馆中的服务员负责 (点菜+上菜 )/ 做菜 ,点完菜需要等菜做好了然后上菜
代码逻辑:固定大小为 2 的线程池,两个线程池同时 (点菜+上菜 )。这时候都需要等待菜做好了然后上菜,而却没有足够线程去做菜
代码
public static void main(String[] args) {
//菜单
List<String> list= Arrays.asList("宫保鸡丁","青椒炒肉","西红柿炒鸡蛋");
//固定大小为 2 的线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
//利用同一个线程池执行任务
executorService.execute(()->{
log.debug("点菜"+list.get(new Random().nextInt(3)));
log.debug("等菜做好...");
利用同一个线程池执行任务
Future<String> submit = executorService.submit(() -> {
return "做好了";
});
//等待做好菜
try {
log.debug(submit.get()+",上菜!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
//利用同一个线程池执行任务
executorService.execute(()->{
log.debug("点菜"+list.get(new Random().nextInt(3)));
log.debug("等菜做好...");
//利用同一个线程池执行任务
Future<String> submit = executorService.submit(() -> {
return "做好了";
});
//等待做好菜
try {
log.debug(submit.get()+"上菜");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
输出
15:33:43 [pool-2-thread-1] c.eight-Demo4 - 点菜西红柿炒鸡蛋
15:33:43 [pool-2-thread-2] c.eight-Demo4 - 点菜青椒炒肉
15:33:43 [pool-2-thread-2] c.eight-Demo4 - 等菜做好...
15:33:43 [pool-2-thread-1] c.eight-Demo4 - 等菜做好...
饥饿问题解决
- 增加线程池的大小,不过不是根本解决方案
- 不同的任务类型,采用不同的线程池,如下代码
代码
public static void main(String[] args) {
//菜单
List<String> list= Arrays.asList("宫保鸡丁","青椒炒肉","西红柿炒鸡蛋");
//固定大小为 2 的线程池 waiter
ExecutorService waiter = Executors.newFixedThreadPool(2);
//固定大小为 2 的线程池 cook
ExecutorService cook = Executors.newFixedThreadPool(2);
//利用线程池 waiter 执行任务
waiter.execute(()->{
log.debug("服务员点菜"+list.get(new Random().nextInt(3)));
log.debug("服务员等菜做好...");
//利用线程池 cook 执行任务
Future<String> submit = cook.submit(() -> {
log.debug("厨师做好菜了");
return "true";
});
//等待线程池 cook 做好菜
try {
submit.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
log.debug("服务员上菜!");
});
//利用线程池 waiter 执行任务
waiter.execute(()->{
log.debug("服务员点菜"+list.get(new Random().nextInt(3)));
log.debug("服务员等菜做好...");
//利用线程池 cook 执行任务
Future<String> submit = cook.submit(() -> {
log.debug("厨师做好菜了");
return "true";
});
//等待线程池 cook 做好菜
try {
submit.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
log.debug("服务员上菜!");
});
}
输出
15:38:14 [pool-2-thread-1] c.eight-Demo4 - 服务员点菜西红柿炒鸡蛋
15:38:14 [pool-2-thread-2] c.eight-Demo4 - 服务员点菜西红柿炒鸡蛋
15:38:14 [pool-2-thread-1] c.eight-Demo4 - 服务员等菜做好...
15:38:14 [pool-2-thread-2] c.eight-Demo4 - 服务员等菜做好...
15:38:14 [pool-3-thread-2] c.eight-Demo4 - 厨师做好菜了
15:38:14 [pool-3-thread-1] c.eight-Demo4 - 厨师做好菜了
15:38:14 [pool-2-thread-2] c.eight-Demo4 - 服务员上菜!
15:38:14 [pool-2-thread-1] c.eight-Demo4 - 服务员上菜!