Java多线程——寺庙问题
2016-03-29 17:02
597 查看
问题简述:某寺庙有老和尚、小和尚若干。庙内有一水缸,由小和尚提水入缸,供老和尚饮用。水缸可容纳30桶水,每次入水、取水仅为一桶,不可同时进行。水取自同一井中,井口狭窄,每次只能容纳一个水桶取水。设有5只水桶,老和尚与小和尚共用。通过Java给出老和尚和小和尚的活动。
代码实现:采用Java的synchronized关键字和线程池技术来进行实现。不得不说的一点是,对于Java的锁机制,若进行了wait(),notify()和notifyAll()操作,则必须在synchronized块中或声明了synchronized的方法中使用,否则会报出IllegalMonitorStateException异常。若synchronized块中使用了某个对象作为锁,则只能对这个锁进行上述三个操作。例如在本例中采用bucketLock的synchronized块中,使用的notifyAll方法必须采用bucketLock.notifyAll()方法,并且只能对块中的锁进行wait,notifyAll,对于其他的锁,是不能进行这些操作的,否则同样会报IllegalMonitorStateException。要命的是,有些时候,这样的异常可能不会显示出来,在执行notifyAll后直接退出该方法,导致错误很难被发现,因此在使用wait(),notify()和notifyAll()时,一定要注意。
运行结果(由于篇幅过长,这里使用在main函数的for循环中i=5的情况):
代码实现:采用Java的synchronized关键字和线程池技术来进行实现。不得不说的一点是,对于Java的锁机制,若进行了wait(),notify()和notifyAll()操作,则必须在synchronized块中或声明了synchronized的方法中使用,否则会报出IllegalMonitorStateException异常。若synchronized块中使用了某个对象作为锁,则只能对这个锁进行上述三个操作。例如在本例中采用bucketLock的synchronized块中,使用的notifyAll方法必须采用bucketLock.notifyAll()方法,并且只能对块中的锁进行wait,notifyAll,对于其他的锁,是不能进行这些操作的,否则同样会报IllegalMonitorStateException。要命的是,有些时候,这样的异常可能不会显示出来,在执行notifyAll后直接退出该方法,导致错误很难被发现,因此在使用wait(),notify()和notifyAll()时,一定要注意。
package com.fhp.testthreadpool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Monk { public static void main(String[] args) { final Temple t = new Temple(); ExecutorService youngMonkService = Executors.newFixedThreadPool(50); ExecutorService oldMonkService = Executors.newFixedThreadPool(50); for(int i = 0; i < 40; i++) { youngMonkService.submit(new Runnable() { @Override public void run() { t.YoungMonk(Thread.currentThread().getName()); } }); oldMonkService.submit(new Runnable() { @Override public void run() { t.OldMonk(Thread.currentThread().getName()); } }); } youngMonkService.shutdown(); oldMonkService.shutdown(); } } class Temple { private int bucket = 5; private int capacity = 30; private int water = 0; private Object bucketLock = new Object(); private Object emptyLock = new Object(); private Object fullLock = new Object(); private Object wellLock = new Object(); public void YoungMonk(String id) { System.out.println("Young monk " + id + ": I am running!"); synchronized(fullLock) { while(capacity <= 0) { try { fullLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } capacity--; } System.out.println("Young monk " + id + ": I am trying to get a bucket..."); synchronized(bucketLock) { while(bucket <= 0) { try { System.out.println("Young monk " + id + ": I\'m waiting for a bucket..."); bucketLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } bucket--; } System.out.println("Young monk " + id + ": Bucket gotten! " + bucket + " buckets remain.I\'m going to the well..."); synchronized(wellLock) { System.out.println("Young monk " + id + ": I\'m containing water..."); } System.out.println("Young monk " + id + ": Going back to the temple..."); synchronized(bucketLock) { bucket++; System.out.println("Young monk " + id + ": Recent bucket:" + bucket); bucketLock.notifyAll(); } synchronized(emptyLock) { water++; // capacity--; System.out.println("Young monk " + id + ": Recent water:" + water); emptyLock.notifyAll(); } System.out.println("Young monk " + id + " is quitting! Recent capacity:" + capacity); } public void OldMonk(String id) { System.out.println("Old monk " + id + ": I am running!"); synchronized(emptyLock) { while(capacity >= 30) { try { emptyLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } capacity++; } System.out.println("Old monk " + id + ": I am trying to get a bucket..."); synchronized(bucketLock) { while(bucket <= 0) { try { System.out.println("Old monk " + id + ": I\'m waiting for a bucket..."); bucketLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } bucket--; } System.out.println("Old monk " + id + ": Bucket gotten! " + bucket + " buckets remain.I\'m going to the jar..."); synchronized(bucketLock) { bucket++; System.out.println("Old monk " + id + ": Recent bucket:" + bucket); bucketLock.notifyAll(); } synchronized(fullLock) { water--; // capacity++; System.out.println("Old monk " + id + ": Recent water:" + water); fullLock.notifyAll(); } System.out.println("Old monk " + id + " is quitting! Recent capacity:" + capacity); } }
运行结果(由于篇幅过长,这里使用在main函数的for循环中i=5的情况):
Young monk pool-1-thread-1: I am running! Young monk pool-1-thread-1: I am trying to get a bucket... Young monk pool-1-thread-1: Bucket gotten! 4 buckets remain.I'm going to the well... Young monk pool-1-thread-1: I'm containing water... Young monk pool-1-thread-1: Going back to the temple... Young monk pool-1-thread-1: Recent bucket:5 Young monk pool-1-thread-1: Recent water:1 Young monk pool-1-thread-1 is quitting! Recent capacity:29 Old monk pool-2-thread-1: I am running! Old monk pool-2-thread-1: I am trying to get a bucket... Old monk pool-2-thread-1: Bucket gotten! 4 buckets remain.I'm going to the jar... Old monk pool-2-thread-1: Recent bucket:5 Old monk pool-2-thread-1: Recent water:0 Old monk pool-2-thread-1 is quitting! Recent capacity:30 Young monk pool-1-thread-2: I am running! Young monk pool-1-thread-2: I am trying to get a bucket... Young monk pool-1-thread-2: Bucket gotten! 4 buckets remain.I'm going to the well... Young monk pool-1-thread-2: I'm containing water... Old monk pool-2-thread-2: I am running! Young monk pool-1-thread-2: Going back to the temple... Young monk pool-1-thread-3: I am running! Young monk pool-1-thread-3: I am trying to get a bucket... Old monk pool-2-thread-3: I am running! Young monk pool-1-thread-2: Recent bucket:5 Young monk pool-1-thread-3: Bucket gotten! 4 buckets remain.I'm going to the well... Young monk pool-1-thread-3: I'm containing water... Young monk pool-1-thread-3: Going back to the temple... Young monk pool-1-thread-3: Recent bucket:5 Young monk pool-1-thread-3: Recent water:1 Young monk pool-1-thread-3 is quitting! Recent capacity:29 Young monk pool-1-thread-2: Recent water:2 Young monk pool-1-thread-2 is quitting! Recent capacity:28 Old monk pool-2-thread-3: I am trying to get a bucket... Old monk pool-2-thread-3: Bucket gotten! 4 buckets remain.I'm going to the jar... Old monk pool-2-thread-2: I am trying to get a bucket... Old monk pool-2-thread-3: Recent bucket:5 Old monk pool-2-thread-3: Recent water:1 Old monk pool-2-thread-3 is quitting! Recent capacity:29 Old monk pool-2-thread-2: Bucket gotten! 4 buckets remain.I'm going to the jar... Old monk pool-2-thread-2: Recent bucket:5 Old monk pool-2-thread-2: Recent water:0 Old monk pool-2-thread-2 is quitting! Recent capacity:30 Young monk pool-1-thread-4: I am running! Young monk pool-1-thread-4: I am trying to get a bucket... Old monk pool-2-thread-4: I am running! Young monk pool-1-thread-4: Bucket gotten! 4 buckets remain.I'm going to the well... Young monk pool-1-thread-4: I'm containing water... Young monk pool-1-thread-5: I am running! Young monk pool-1-thread-5: I am trying to get a bucket... Young monk pool-1-thread-4: Going back to the temple... Young monk pool-1-thread-4: Recent bucket:4 Young monk pool-1-thread-5: Bucket gotten! 3 buckets remain.I'm going to the well... Young monk pool-1-thread-5: I'm containing water... Young monk pool-1-thread-5: Going back to the temple... Old monk pool-2-thread-5: I am running! Young monk pool-1-thread-5: Recent bucket:5 Young monk pool-1-thread-5: Recent water:1 Young monk pool-1-thread-5 is quitting! Recent capacity:29 Old monk pool-2-thread-4: I am trying to get a bucket... Old monk pool-2-thread-4: Bucket gotten! 4 buckets remain.I'm going to the jar... Old monk pool-2-thread-4: Recent bucket:5 Old monk pool-2-thread-4: Recent water:1 Old monk pool-2-thread-4 is quitting! Recent capacity:29 Old monk pool-2-thread-5: I am trying to get a bucket... Old monk pool-2-thread-5: Bucket gotten! 4 buckets remain.I'm going to the jar... Old monk pool-2-thread-5: Recent bucket:5 Old monk pool-2-thread-5: Recent water:0 Old monk pool-2-thread-5 is quitting! Recent capacity:30 Young monk pool-1-thread-4: Recent water:2 Young monk pool-1-thread-4 is quitting! Recent capacity:30
相关文章推荐
- Spring mvc 配置事务的注意点
- java方法调用之单分派与多分派(二)
- [JAVA]学习笔记(三)——访问权限控制
- Spring注解
- JAVA内存模型(Java Memory Model)
- java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "javamelody jenkins
- Java 实现文章汉字关键词(违禁词)识别2.0
- maven+Spring4(restful)整合
- 双缓冲的使用—java语言
- JAVA设计模式之单例模式
- 关于在myeclipse中导入工程所遇到的问题,解决办法
- java面向对象编程杂谈
- bzoj3198 spring hash&容斥原理
- java智力拼图小游戏
- java锁的种类以及辨析
- JDBC驱动自身问题引发的FullGC
- JAVA打印二维码图片自定义高度
- JavaEE_Servlet的页面跳转 和 参数的传递
- 2016.03.29///Java学习记录③
- 基于Springmvc的登录权限拦截器