1.烧水泡茶
1.需求:
代码实现
2.analysis
并发编程分析思路:
分工,同步,互斥。
先分析同步:
烧水和洗茶具是同步的,所以分为两个任务。一个任务烧水,一个任务洗茶具。
优化分析:将一个任务做为主任务
一种最优的分工方案可以是下图所示的这样:用两个线程 T1 和 T2 来完成烧水泡茶程序,T1 负责洗水壶、烧开水、泡茶这三道工序,T2 负责洗茶壶、洗茶杯、拿茶叶三道工序,其中 T1 在执行泡茶这道工序时需要等待 T2 完成拿茶叶的工序。对于 T1 的这个等待动作,你应该可以想出很多种办法,例如 Thread.join()、CountDownLatch,甚至阻塞队列都可以解决,不过今天我们用 Future 特性来实现。
3.code
ShaoShuiMain
···
packagecn.pl.future.shaoshuiTest;
importjava.util.concurrent.ExecutionException;
importjava.util.concurrent.FutureTask;
importcn.pl.future.shaoshuiTest.childThread.ShaoShui;
importcn.pl.future.shaoshuiTest.childThread.XiTools;
publicclassShaoShuiMain{
publicstaticvoidmain(String[]args)throwsInterruptedException,ExecutionException{
//任务2 洗工具
FutureTask<String>f2=newFutureTask<>(newXiTools());
//任务1 烧水
FutureTask<String>f1=newFutureTask<>(newShaoShui(f2));
Threadt1=newThread(f1);
Threadt2=newThread(f2);
t1.start();
t2.start();
//等待上茶
System.out.println(f1.get());
}
}
···
ShaoShui
···
packagecn.pl.future.shaoshuiTest.childThread;
importjava.util.concurrent.Callable;
importjava.util.concurrent.FutureTask;
importjava.util.concurrent.TimeUnit;
publicclassShaoShuiimplementsCallable<String>{
FutureTask<String>f2;
publicShaoShui(FutureTask<String>f2) {
// TODO Auto-generated constructor stub
this.f2=f2;
}
@Override
publicStringcall()throwsException{
// TODO Auto-generated method stub
System.out.println("T1: 洗水壶...");
TimeUnit.SECONDS.sleep(1);
System.out.println("T1: 烧开水...");
// 获取 T2 线程的茶叶
Stringtf=f2.get();
TimeUnit.SECONDS.sleep(15);
System.out.println("T1: 拿到茶叶:"+tf);
System.out.println("T1: 泡茶...");
return" 上茶:"+tf;
}
}
···
XiTools
packagecn.pl.future.shaoshuiTest.childThread;
importjava.util.concurrent.Callable;
importjava.util.concurrent.TimeUnit;
publicclassXiToolsimplementsCallable<String>{
@Override
publicStringcall()throwsException{
// TODO Auto-generated method stub
System.out.println("T2: 洗茶壶...");
TimeUnit.SECONDS.sleep(1);
System.out.println("T2: 洗茶杯...");
TimeUnit.SECONDS.sleep(2);
System.out.println("T2: 拿茶叶...");
TimeUnit.SECONDS.sleep(1);
return" 龙井 ";
}
}
运行结果: