工作线程
例子
package com.huangbei.test2;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Slf4j(topic = "c.Test-线程池工作线程问题")
public class Test10 {
static List<String> MENU = Arrays.asList("清水白菜", "宫保鸡丁", "红烧肉", "番茄炒鸡蛋");
static Random RANDOM = new Random();
static String cook() {
return MENU.get(RANDOM.nextInt(MENU.size()));
}
public static void main(String[] args) {
//创建2个线程的线程池
//模拟服务员和厨师,服务员的工作是点餐和上菜,厨师的工作是做菜
//一开始,两个线程都可以充当服务员和厨师的工作
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(() -> {
log.debug("点餐...");
//通知厨师做菜
Future<String> food = pool.submit(() -> {
log.debug("做菜...");
return cook();
});
try {
log.debug("上菜:{}", food.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
pool.execute(() -> {
log.debug("点餐...");
//通知厨师做菜
Future<String> food = pool.submit(() -> {
log.debug("做菜...");
return cook();
});
try {
log.debug("上菜:{}", food.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
}
在上面的例子中,线程池的线程数量为2,而这两个线程都在执行服务员的工作,等待厨师的线程的执行结果,而由于线程池已经没有额外的线程资源,因此厨师无法做菜,而服务员线程也无法继续执行,造成了整个程序无法正常运行。
解决办法:
让服务员任务和厨师任务分别由两个线程池执行。
package com.huangbei.test2;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Slf4j(topic = "c.Test-线程池工作线程问题")
public class Test11 {
static List<String> MENU = Arrays.asList("清水白菜", "宫保鸡丁", "红烧肉", "番茄炒鸡蛋");
static Random RANDOM = new Random();
static String cook() {
return MENU.get(RANDOM.nextInt(MENU.size()));
}
public static void main(String[] args) {
//创建2个线程的线程池
//模拟服务员和厨师,服务员的工作是点餐和上菜,厨师的工作是做菜
//一开始,两个线程都可以充当服务员和厨师的工作
ExecutorService waiterPool = Executors.newFixedThreadPool(1);
ExecutorService cookPool = Executors.newFixedThreadPool(1);
waiterPool.execute(() -> {
log.debug("点餐...");
//通知厨师做菜
Future<String> food = cookPool.submit(() -> {
log.debug("做菜...");
return cook();
});
try {
log.debug("上菜:{}", food.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
waiterPool.execute(() -> {
log.debug("点餐...");
//通知厨师做菜
Future<String> food = cookPool.submit(() -> {
log.debug("做菜...");
return cook();
});
try {
log.debug("上菜:{}", food.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
}