您的位置:首页 > 编程语言 > Java开发

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()时,一定要注意。

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: