在多线程场景下,有A、B两种任务,都是多线程并行执行,但A、B直接有先后关系,在A线程中启动B,B执行完成后,A继续执行。
如果A、B都使用同一个线程池,则可能出现饥饿线程,即所有的线程都被A任务抢走,等待线程池中有空闲线程才能执行B,但是B又不能执行,会出现类似死锁的情形。
package thread;
import java.util.concurrent.*;
public class HungryThread {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(()->{
System.out.println("开始点菜。。。1");
Future<String> cook = executorService.submit(() -> {
System.out.println("做菜1");
return "菜做好了1";
});
try {
cook.get();
System.out.println("上菜1");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
executorService.submit(()->{
System.out.println("开始点菜。。。2");
Future<String> cook = executorService.submit(() -> {
System.out.println("做菜2");
return "菜做好了2";
});
try {
cook.get();
System.out.println("上菜2");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
}
结果:A线程被阻塞住,B任务被放在队列中等待执行:
解决办法:
不同的任务使用不同的线程池
package thread;
import java.util.concurrent.*;
public class HungryThread {
public static void main(String[] args) {
// 任务A的线程池
ExecutorService executorServiceA = Executors.newFixedThreadPool(2);
// 任务B的线程池
ExecutorService executorServiceB = Executors.newFixedThreadPool(2);
executorServiceA.submit(()->{
System.out.println("开始点菜。。。1");
Future<String> cook = executorServiceB.submit(() -> {
System.out.println("做菜1");
return "菜做好了1";
});
try {
cook.get();
System.out.println("上菜1");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
executorServiceA.submit(()->{
System.out.println("开始点菜。。。2");
Future<String> cook = executorServiceB.submit(() -> {
System.out.println("做菜2");
return "菜做好了2";
});
try {
cook.get();
System.out.println("上菜2");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
}