使用 CompletionService 优化询价应用。
获取价格与保存方法
private static Integer getPriceByS1() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
}
private static Integer getPriceByS2() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
}
private static Integer getPriceByS3() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 3;
}
private static void save(Integer i) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("save " + i);
}
串行执行
private static void func1() {
Integer priceByS1 = getPriceByS1();
save(priceByS1);
Integer priceByS2 = getPriceByS2();
save(priceByS2);
Integer priceByS3 = getPriceByS3();
save(priceByS3);
}
ThreadPoolExecutor+Future 优化
private static void func2() throws Exception {
Integer r = null;
ExecutorService executor = Executors.newFixedThreadPool(3);
Future f1 = executor.submit(() -> getPriceByS1());
// 异步向电商S2询价
Future<Integer> f2 =
executor.submit(
() -> getPriceByS2());
// 异步向电商S3询价
Future<Integer> f3 =
executor.submit(
() -> getPriceByS3());
// 获取电商S1报价并保存
System.out.println("f1.get()");
r = (Integer) f1.get();
Integer finalR = r;
executor.execute(() -> save(finalR));
System.out.println("f2.get()");
// 获取电商S2报价并保存
r = f2.get();
Integer finalR1 = r;
executor.execute(() -> save(finalR1));
System.out.println("f3.get()");
// 获取电商S3报价并保存
r = f3.get();
Integer finalR2 = r;
executor.execute(() -> save(finalR2));
}
如果获取电商 S1 报价的耗时很长,那么即便获取电商 S2 报价的耗时很短,也无法让保存 S2 报价的操作先执行,因为这个主线程都阻塞在了 f1.get() 操作上。
使用 CompletionService 优化
private static void func3() throws Exception{
// 创建线程池
ExecutorService executor =
Executors.newFixedThreadPool(3);
// 创建CompletionService
CompletionService<Integer> cs = new
ExecutorCompletionService<>(executor);
// 异步向电商S1询价
cs.submit(() -> getPriceByS1());
// 异步向电商S2询价
cs.submit(() -> getPriceByS2());
// 异步向电商S3询价
cs.submit(() -> getPriceByS3());
// 将询价结果异步保存到数据库
for (int i = 0; i < 3; i++) {
Integer r = cs.take().get();
executor.execute(() -> save(r));
}
}
main
public static void main(String[] args) throws Exception {
long l = System.currentTimeMillis();
// func1();
// func2();
func3();
long l1 = System.currentTimeMillis();
System.out.println("耗时:" + (l1 - l) + " 毫秒");
}