1. 定义
让有限的工作线程(Worker Thread)来轮流异步处理无限多的任务。也可以将其归类为分工模式,它的典型实现
就是线程池,也体现了经典设计模式中的享元模式。
2. 饥饿
固定大小线程池会有饥饿现象
两个工人是同一个线程池中的两个线程
他们要做的事情是:为客人点餐和到后厨做菜,这是两个阶段的工作
客人点餐:必须先点完餐,等菜做好,上菜,在此期间处理点餐的工人必须等待
后厨做菜:没啥说的,做就是了
比如工人A 处理了点餐任务,接下来它要等着 工人B 把菜做好,然后上菜,他俩也配合的蛮好
但现在同时来了两个客人,这个时候工人A 和工人B 都去处理点餐了,这时没人做饭了,饥饿
public class TestStarvation {
static final List<String> MENU = Arrays.asList("地三鲜", "宫保鸡丁", "辣子鸡丁", "烤鸡翅");
static Random RANDOM = new Random();
static String cooking() {
return MENU.get(RANDOM.nextInt(MENU.size()));
}
public static void main(String[] args) {
ExecutorService waiterPool = Executors.newFixedThreadPool(2);
waiterPool.execute(() -> {
System.out.println("处理点餐...");
Future<String> f = waiterPool.submit(() -> {
System.out.println("做菜");
return cooking();
});
try {
System.out.println("上菜: " + f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
waiterPool.execute(() -> {
System.out.println("处理点餐...");
Future<String> f = waiterPool.submit(() -> {
System.out.println("做菜");
return cooking();
});
try {
System.out.println("上菜: " + f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
}
}
解决方案:
不同的事交给不同线程池处理
public class TestStarvation {
static final List<String> MENU = Arrays.asList("地三鲜", "宫保鸡丁", "辣子鸡丁", "烤鸡翅");
static Random RANDOM = new Random();
static String cooking() {
return MENU.get(RANDOM.nextInt(MENU.size()));
}
public static void main(String[] args) {
ExecutorService waiterPool = Executors.newFixedThreadPool(2);
ExecutorService cookPool = Executors.newFixedThreadPool(1);
waiterPool.execute(() -> {
System.out.println("处理点餐...");
Future<String> f = cookPool.submit(() -> {
System.out.println("做菜");
return cooking();
});
try {
System.out.println("上菜: " + f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
waiterPool.execute(() -> {
System.out.println("处理点餐...");
Future<String> f = cookPool.submit(() -> {
System.out.println("做菜");
return cooking();
});
try {
System.out.println("上菜: " + f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
}
}