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

这篇文章我们来写一个小例子,充分利用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,这个协作就讲到这里,下一篇我们再来看看比较经典的 消费者与生产者模式;





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值