[JAVA]等待通知机制的2种实现
2017-12-28 22:28
477 查看
最近笔者在空闲之余,温习了下JAVA多线程编程。经常看,却经常忘记。可能是由于用的不多的缘故吧。这里针对多线程的等待通知的机制的2种实现进行总结。加深理解和认识。
大家去餐馆吃饭的时候,会取号进行”等待“。等到号了,餐馆工作人员会”通知“你前去就餐。
这就是一个简单的等待通知的例子。好了,接下来介绍下它的2种实现。
这里通过2种实现,对等待通知进制进行了一个小结。例子可能不太恰当。欢迎批评指正。
等待通知机制
首先介绍下什么是等待通知机制。这里举一个生活的例子。大家去餐馆吃饭的时候,会取号进行”等待“。等到号了,餐馆工作人员会”通知“你前去就餐。
这就是一个简单的等待通知的例子。好了,接下来介绍下它的2种实现。
wait()和notify()实现等待通知机制
源码见Github去餐馆就餐的客人(等待者)
package com.zju.javastudy.waitnotify.demo1; /** * @author Arthur * @Date 2017/12/28 * @Decription: 饿着的人,去餐馆取号,等待者 */ public class HungryPeople implements Runnable { /** * 座位 */ private Object seat; public HungryPeople(Object seat) { this.seat = seat; } @Override public void run() { synchronized (seat) { try { System.out.println("HungryPeople:去餐馆吃饭,先取号..."); seat.wait();//等待叫号 System.out.println("HungryPeople:到号,有位置了!可以吃饭了!"); } catch (InterruptedException e) { e.printStackTrace(); } } } }
餐馆(通知者)
package com.zju.javastudy.waitnotify.demo1; /** * @author Arthur * @Date 2017/12/28 * @Decription: 餐馆,通知者 */ public class Restaurant implements Runnable { /** * 座位,实质就是锁 */ private Object seat; public Restaurant(Object o) { this.seat = o; } @Override public void run() { try { //模拟等待 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (seat) { System.out.println("Restaurant:有空位,通知客人来就餐..."); seat.notify();//通知到号 System.out.println("Restaurant:完成通知"); } } }
测试
package com.zju.javastudy.waitnotidy.demo1; import com.zju.javastudy.waitnotify.demo1.HungryPeople; import com.zju.javastudy.waitnotify.demo1.Restaurant; import org.junit.Test; import static sun.jvm.hotspot.runtime.PerfMemory.start; /** * @author Arthur * @Date 2017/12/28 * @Decription: 餐馆取号吃饭的测试例子 */ public class WaitNotidyTest1 { @Test public void test() throws InterruptedException { Object seat = new Object();//座位 Restaurant restaurant = new Restaurant(seat); HungryPeople hungryPeople = new HungryPeople(seat); Thread hungryPeopleThread = new Thread(hungryPeople); hungryPeopleThread.start(); Thread restaurantThread = new Thread(restaurant); restaurantThread.start(); //子线程结束后,再结束main线程 hungryPeopleThread.join(); restaurantThread.join(); } }
结果
使用Condition实现部分通知
源码见Github去餐馆就餐的客人(等待者)
package com.zju.javastudy.waitnotify.demo2; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * @author Arthur * @Date 2017/12/28 * @Decription: 饿着的人,去餐馆取号,等待者 */ public class HungryPeople implements Runnable { /** * 所有座位 */ private ReentrantLock allSeat; /** * 等待的桌(大桌/小桌) */ private Condition seat; public HungryPeople(ReentrantLock allSeat,Condition seat) { this.allSeat = allSeat; this.seat = seat; } @Override public void run() { allSeat.lock(); try { seat.await(); System.out.println(Thread.currentThread().getName()+":等到位置"); } catch (InterruptedException e) { e.printStackTrace(); }finally { allSeat.unlock(); } } }
餐馆(通知者)
package com.zju.javastudy.waitnotify.demo2; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * @author Arthur * @Date 2017/12/28 * @Decription: 餐馆,通知者 */ public class Restaurant implements Runnable { /** * 所有座位 */ private ReentrantLock allSeat; /** * 小桌 */ private Condition smallSeat; /** * 大桌 */ private Condition bigSeat; public Restaurant(ReentrantLock allSeat,Condition smallSeat, Condition bigSeat) { this.allSeat = allSeat; this.smallSeat = smallSeat; this.bigSeat = bigSeat; } @Override public void run() { //这里模拟通知大桌 try { allSeat.lock(); Thread.sleep(2000); System.out.println("Restaurant:有大桌空位,通知客人来就餐..."); bigSeat.signalAll(); System.out.println("Restaurant:完成大桌通知"); } catch (InterruptedException e) { e.printStackTrace(); }finally { allSeat.unlock(); } //这里模拟通知小桌 try { Thread.sleep(3000); allSeat.lock(); System.out.println("Restaurant:有小桌空位,通知客人来就餐..."); smallSeat.signalAll(); System.out.println("Restaurant:完成小桌通知"); } catch (InterruptedException e) { e.printStackTrace(); }finally { allSeat.unlock(); } } }
测试
package com.zju.javastudy.waitnotidy.demo2; import com.zju.javastudy.waitnotify.demo2.HungryPeople; import com.zju.javastudy.waitnotify.demo2.Restaurant; import org.junit.Test; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * @author Arthur * @Date 2017/12/28 * @Decription: 餐馆取号吃饭的测试例子 */ public class WaitNotidyTest2 { @Test public void test() throws InterruptedException { ReentrantLock allSeat = new ReentrantLock();//座位 Condition smallSeat = allSeat.newCondition();//小桌 Condition bigSeat = allSeat.newCondition();//大桌 //实例化 餐馆,小桌客人和大桌客人 Restaurant restaurant = new Restaurant(allSeat,smallSeat,bigSeat); HungryPeople hungryPeopleWaitSmall = new HungryPeople(allSeat,smallSeat); HungryPeople hungryPeopleWaitBig = new HungryPeople(allSeat,bigSeat); //小桌客人线程 Thread hungryPeopleWaitSmallThread = new Thread(hungryPeopleWaitSmall); hungryPeopleWaitSmallThread.setName("smallSeatPeople"); //大桌客人线程 Thread hungryPeopleWaitBigThread = new Thread(hungryPeopleWaitBig); hungryPeopleWaitBigThread.setName("bigSeatPeople"); //餐馆线程 Thread restaurantThread = new Thread(restaurant); //开始模拟 hungryPeopleWaitSmallThread.start(); hungryPeopleWaitBigThread.start(); restaurantThread.start(); //子线程结束再结束main线程 hungryPeopleWaitSmallThread.join(); hungryPeopleWaitBigThread.join(); restaurantThread.join(); } }
结果
这里通过2种实现,对等待通知进制进行了一个小结。例子可能不太恰当。欢迎批评指正。
相关文章推荐
- 二 Java利用等待/通知机制实现一个线程池
- Java 并发编程-再谈 AbstractQueuedSynchronizer 2:共享模式与基于 Condition 的等待 / 通知机制实现
- 生产者和消费者问题【java等待通知机制实现】
- java多线程的等待和通知机制,两种实现方法
- Java线程通信与协作的解决方案——等待/通知机制
- Java多线程Condition实现等待/通知
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
- Java中的等待/通知机制(wait/notify)
- 多线程 等待/通知机制的实现
- Condition实现生产者消费者模式(等待/通知机制)
- Condition实现生产者消费者模式(等待/通知机制)
- Java等待/通知机制:生产者-消费者问题
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
- java多线程的等待和通知机制
- java线程等待/通知机制及中断
- Java线程之间的通信-等待/通知机制
- java多线程系列(三)---等待通知机制
- 如何使用Lock接口来实现等待/通知机制