1. package org.example.concurrency.test.n7;
  2. import lombok.extern.slf4j.Slf4j;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5. import java.util.concurrent.Future;
  6. /**
  7. * @author huskyui
  8. */
  9. @Slf4j
  10. public class TestStarvation {
  11. public static void main(String[] args) {
  12. ExecutorService pool = Executors.newFixedThreadPool(2);
  13. pool.execute(()->{
  14. log.debug("处理点餐");
  15. Future<String> f = pool.submit(() -> {
  16. log.debug("做菜");
  17. return "123";
  18. });
  19. try{
  20. log.debug("上菜 {}",f.get());
  21. }catch (Exception e){
  22. e.printStackTrace();
  23. }
  24. });
  25. pool.execute(()->{
  26. log.debug("处理点餐");
  27. Future<String> f = pool.submit(() -> {
  28. log.debug("做菜");
  29. return "456";
  30. });
  31. try{
  32. log.debug("上菜 {}",f.get());
  33. }catch (Exception e){
  34. e.printStackTrace();
  35. }
  36. });
  37. }
  38. }

现象:
image.png
jstack pid
image.png
两个线程并没有死锁

问题

由于线程池只有两个线程,可以使用。

解决方法一

增加线程数
image.png
但有缺陷,上述代码只是模拟两个并发情况下,如果是三个,也就又解决不了了

正确处理

不同的任务,交给不同的线程池处理

  1. ExecutorService waiterPool = Executors.newFixedThreadPool(1);
  2. ExecutorService cookPool = Executors.newFixedThreadPool(1);
  3. waiterPool.execute(()->{
  4. log.debug("处理点餐");
  5. Future<String> f = cookPool.submit(() -> {
  6. log.debug("做菜");
  7. return "123";
  8. });
  9. try{
  10. log.debug("上菜 {}",f.get());
  11. }catch (Exception e){
  12. e.printStackTrace();
  13. }
  14. });
  15. waiterPool.execute(()->{
  16. log.debug("处理点餐");
  17. Future<String> f = cookPool.submit(() -> {
  18. log.debug("做菜");
  19. return "456";
  20. });
  21. try{
  22. log.debug("上菜 {}",f.get());
  23. }catch (Exception e){
  24. e.printStackTrace();
  25. }
  26. });