基础篇:线程间的协作之积累能量---放大招(九)

来源:互联网 发布:webrtc python 编辑:程序博客网 时间:2024/06/05 02:26

这篇文章我们来写一个小例子,充分利用notifyAll与wait等方法,来完成一个模拟游戏中不停的 “积累能量---放大招” 的例子!

我们先看运行结果,再看代码:

***********************************************************************************************

开始第1次积累能量
第1次积累能量完毕!
开始第1次使用能量释放大招
第1次使用能量释放大招完毕!
开始第2次积累能量
第2次积累能量完毕!
开始第2次使用能量释放大招
第2次使用能量释放大招完毕!
开始第3次积累能量
第3次积累能量完毕!
开始第3次使用能量释放大招
第3次使用能量释放大招完毕!
开始第4次积累能量
第4次积累能量完毕!
开始第4次使用能量释放大招
第4次使用能量释放大招完毕!
开始第5次积累能量
第5次积累能量完毕!
开始第5次使用能量释放大招
第5次使用能量释放大招完毕!
***********************************************************************************************


//游戏人物class Role{//能量是否积累完毕,这是一个信号量private boolean energyed = false;private int count = 0;//开始积累能量public void energyOn(){while(!Thread.currentThread().isInterrupted()){synchronized (this) {try {//一直检查能量状态,如果当前没有能量,则先积累能量完毕,再暂停自己并唤醒放大招的线程while(!energyed){//1.5秒才能积累完毕System.out.println("开始第"+ (++count) +"次积累能量");TimeUnit.MILLISECONDS.sleep(1500);energyed = true;System.out.println("第"+ count +"次积累能量完毕!");notifyAll();wait();}} catch (InterruptedException e) {e.printStackTrace();}}}}//使用能量public void energyUse(){while(!Thread.currentThread().isInterrupted()){synchronized(this) {try {//一直检查能量状态,如果当前有能量,则放大招后再暂停自己且唤醒积累能量的线程while(energyed){System.out.println("开始第"+count+"次使用能量释放大招");energyed = false;System.out.println("第"+count+"次使用能量释放大招完毕!");notifyAll();wait();}} catch (Exception e) {e.printStackTrace();}}}}}

//一个简单的协作,全面演示wait,notify;所有的协作基本都是由一个信号量来进行流程控制的public static void teamwork(){//场景:你是个游戏人物,你在放大招之前需要等待积累能力...能力积累完后你立马放大招...放完又等待积累能力...周而复始ExecutorService exec = Executors.newCachedThreadPool();final Role role = new Role();//执行使用能量释放大招线程exec.execute(new Runnable() {public void run() {role.energyUse();}});//执行积累能量线程exec.execute(new Runnable() {public void run() {role.energyOn();}});}

如代码中所示,我们来分解一下执行顺序:

1> role的energyOn()方法不断的积累能量,前提是它发现当前已经没有能量了;

2> 当它积累完能量后,它先唤醒等待此对象锁的线程然后自己进入等待状态;

3> 当它进入等待状态后,将释放对象锁,由此,等待使用能量的线程获得了执行机会;

4> 等待使用能量的线程先判断是否有能量可用,如果有,它开始消耗能量;

5> 消耗完能量后,它先唤醒等待此对象锁的线程然后自己进入等待状态;

6> 积累能量的线程被唤醒.........


稍微提一下,我们在while循环中的判断条件是当前线程没有被中断,我们可以调用Thread.interrupted()来打断当前线程的执行;


OK,这个协作就讲到这里,下一篇我们再来看看比较经典的 消费者与生产者模式;





0 0
原创粉丝点击