go to  ForumEasy.com   
JavaPro
Home » Archive » Message


[Email To Friend][View in Live Context][prev topic « prev post | next post » next topic]
  notifyAll() in practice
 
Subject: notifyAll() in practice
Author: EricJ
In response to: notify() in practice
Posted on: 02/24/2007 02:55:58 AM

/**
 * 
 * A sample code demonstrate how notifyAll() and wait() interact with each other
 *
 */
public class ResourcePoolTester extends Thread
{    
    ResourcePool pool = null;
    int num;
    
    public ResourcePoolTester(ResourcePool pool, int num)
    {
        this.pool = pool;
        this.num = num;
    }
    
    public synchronized void run()
    {
        if(num>0){ // check out
            System.out.println("Thread [" + Thread.currentThread().getId() +
                               "] is about to check out resources of: " + num);
            pool.checkOut(num);
            
        }else{  // check in
            num = -num;
            System.out.println("Thread [" + Thread.currentThread().getId() +
                               "] is about to check in resources of: " + num);
            pool.checkIn(num);
            
        }
    }
    
    
    public static void main(String[] args)
    {
        
        // initialize the resource pool  
        ResourcePool pool = new ResourcePool(2);
        System.out.println("The pool starts with size of: " + pool.size());
        
        // 5 threads to check out resuorce from the pool
        ResourcePoolTester t1 = new ResourcePoolTester(pool, 1); 
        ResourcePoolTester t2 = new ResourcePoolTester(pool, 2); 
        ResourcePoolTester t3 = new ResourcePoolTester(pool, 3); 
        ResourcePoolTester t4 = new ResourcePoolTester(pool, 4); 
        ResourcePoolTester t5 = new ResourcePoolTester(pool, 5); 
        
        t1.start(); // returns immediately
        t2.start(); // going to wait
        t3.start(); // going to wait
        t4.start(); // going to wait
        t5.start(); // going to wait
        
        // 2 threads to check in resource into the pool
        ResourcePoolTester t6 = new ResourcePoolTester(pool, -6); 
        t6.start();
        try{
            Thread.sleep(1000);  // just a second
        }catch(Exception e){
        }
        ResourcePoolTester t7 = new ResourcePoolTester(pool, -9); 
        t7.start();
        
        try{
            t1.join();
            t2.join();
            t3.join();
            t4.join();
            t5.join();
            t6.join();
            t7.join();
        }catch(Exception e){
        }
        
        System.out.println("The pool ends up with size of: " + pool.size());
        
    }
}


class ResourcePool
{
    /**
     *  the count monitoring how many resource currently reside in the pool
     */
    private int count;

    public ResourcePool(int count){
        this.count = count;
    }
    
    public synchronized void checkOut(int num)
    {
        // check to see if there are enough resources? 
        while(count<num){
            System.out.println("Thread [" + Thread.currentThread().getId() +
                               "] is waiting with pool size = " + size());
            try{
                wait(); // wait until there are enough resources
            }catch(Exception e){                    
            }
            System.out.println("Thread [" + Thread.currentThread().getId() +
                               "] wakes up with pool size = " + size());
        }
        count -= num; // check-out
        System.out.println("Thread [" + Thread.currentThread().getId() +
                            "] returns with pool size = " + size());
    }
    
    public synchronized void checkIn(int num)
    {
        count += num; // check-in
        
        notifyAll();
        
        System.out.println("Thread [" + Thread.currentThread().getId() +
                           "] checked in with pool size = " + size());
    }
    
    public synchronized int size(){
        return count;
    }
    
}


Here are the outputs:

The pool starts with size of: 2
Thread [7] is about to check out resources of: 1
Thread [7] returns with pool size = 1
Thread [8] is about to check out resources of: 2
Thread [8] is waiting with pool size = 1
Thread [9] is about to check out resources of: 3
Thread [9] is waiting with pool size = 1
Thread [10] is about to check out resources of: 4
Thread [10] is waiting with pool size = 1
Thread [11] is about to check out resources of: 5
Thread [11] is waiting with pool size = 1
Thread [12] is about to check in resources of: 6
Thread [12] checked in with pool size = 7
Thread [8] wakes up with pool size = 7
Thread [8] returns with pool size = 5
Thread [9] wakes up with pool size = 5
Thread [9] returns with pool size = 2
Thread [10] wakes up with pool size = 2
Thread [10] is waiting with pool size = 2
Thread [11] wakes up with pool size = 2
Thread [11] is waiting with pool size = 2
Thread [13] is about to check in resources of: 9
Thread [13] checked in with pool size = 11
Thread [10] wakes up with pool size = 11
Thread [10] returns with pool size = 7
Thread [11] wakes up with pool size = 7
Thread [11] returns with pool size = 2
The pool ends up with size of: 2

Observations:
  • t1-Thread[7] checks out resource immediately since there are enough (2) resources for what it is asking (1);
  • t2-Thread[8] ~ t5-Thread[11] have to wait until more resources are available;
  • after t6-Thread[12] checks in 6 resources, its notification gets all waiting threads: t2-Thread[8], t3-Thread[9] , t4-Thread[10] and t5-Thread[11] to wake up. Among them, t2-Thread[8] and t3-Thread[9] return, but t4-Thread[10] and t5-Thread[11] have to continue waiting until available;
  • again, t7-Thread[13]'s check-in notifyAll() and gets all the restl waiting threads: t4-Thread[10] and t5-Thread[11] to wake up and return;
  • all threads have the fair chance to wake up the check their own status to see what to do next.


     

    > On 02/24/2007 02:01:10 AM EricJ wrote:

    /**
     * 
     * A sample code demonstrate how notify() and wait() interact with each other
     *
     */
    public class ResourcePoolTester extends Thread
    {    
        ResourcePool pool = null;
        int num;
        
        public ResourcePoolTester(ResourcePool pool, int num)
        {
            this.pool = pool;
            this.num = num;
        }
        
        public synchronized void run()
        {
            if(num>0){ // check out
                System.out.println("Thread [" + Thread.currentThread().getId() +
                                   "] is about to check out resources of: " + num);
                pool.checkOut(num);
                
            }else{  // check in
                num = -num;
                System.out.println("Thread [" + Thread.currentThread().getId() +
                                   "] is about to check in resources of: " + num);
                pool.checkIn(num);
                
            }
        }
        
        
        public static void main(String[] args)
        {
            
            // initialize the resource pool  
            ResourcePool pool = new ResourcePool(2);
            System.out.println("The pool starts with size of: " + pool.size());
            
            // 5 threads to check out resuorce from the pool
            ResourcePoolTester t1 = new ResourcePoolTester(pool, 1); 
            ResourcePoolTester t2 = new ResourcePoolTester(pool, 2); 
            ResourcePoolTester t3 = new ResourcePoolTester(pool, 3); 
            ResourcePoolTester t4 = new ResourcePoolTester(pool, 4); 
            ResourcePoolTester t5 = new ResourcePoolTester(pool, 5); 
            
            t1.start(); // returns immediately
            t2.start(); // going to wait
            t3.start(); // going to wait
            t4.start(); // going to wait
            t5.start(); // going to wait
            
            // 2 threads to check in resource into the pool
            ResourcePoolTester t6 = new ResourcePoolTester(pool, -6); 
            t6.start();
            try{
                Thread.sleep(1000);  // just a second
            }catch(Exception e){
            }
            ResourcePoolTester t7 = new ResourcePoolTester(pool, -9); 
            t7.start();
            
            try{
                t1.join();
                t2.join();
                t3.join();
                t4.join();
                t5.join();
                t6.join();
                t7.join();
            }catch(Exception e){
            }
            
            System.out.println("The pool ends up with size of: " + pool.size());
            
        }
    }
    
    
    class ResourcePool
    {
        /**
         *  the count monitoring how many resource currently reside in the pool
         */
        private int count;
    
        public ResourcePool(int count){
            this.count = count;
        }
        
        public synchronized void checkOut(int num)
        {
            // check to see if there are enough resources? 
            while(count<num){
                System.out.println("Thread [" + Thread.currentThread().getId() +
                                   "] is waiting with pool size = " + size());
                try{
                    wait(); // wait until there are enough resources
                }catch(Exception e){                    
                }
                System.out.println("Thread [" + Thread.currentThread().getId() +
                                   "] wakes up with pool size = " + size());
            }
            count -= num; // check-out
            System.out.println("Thread [" + Thread.currentThread().getId() +
                                "] returns with pool size = " + size());
        }
        
        public synchronized void checkIn(int num)
        {
            count += num; // check-in
            
            notify();
            
            System.out.println("Thread [" + Thread.currentThread().getId() +
                               "] checked in with pool size = " + size());
        }
        
        public synchronized int size(){
            return count;
        }
        
    }


    Here are the outputs:

    The pool starts with size of: 2
    Thread [7] is about to check out resources of: 1
    Thread [7] returns with pool size = 1
    Thread [8] is about to check out resources of: 2
    Thread [8] is waiting with pool size = 1
    Thread [9] is about to check out resources of: 3
    Thread [9] is waiting with pool size = 1
    Thread [10] is about to check out resources of: 4
    Thread [10] is waiting with pool size = 1
    Thread [11] is about to check out resources of: 5
    Thread [11] is waiting with pool size = 1
    Thread [12] is about to check in resources of: 6
    Thread [12] checked in with pool size = 7
    Thread [8] wakes up with pool size = 7
    Thread [8] returns with pool size = 5
    Thread [13] is about to check in resources of: 9
    Thread [13] checked in with pool size = 14
    Thread [9] wakes up with pool size = 14
    Thread [9] returns with pool size = 11

    Observations:
  • t1-Thread[7] checks out resource immediately since there are enough (2) resources for what it is asking (1);
  • t2-Thread[8] ~ t5-Thread[11] have to wait until more resources are available;
  • after t6-Thread[12] checks in 6 resources, its notification gets only one thread t2-Thread[8] wake up even though there are enough resources (5 left) in the pool for t3-Thread[9] (it ask for 3), t4-Thread[10] (it asks for 4) or t5-Thread[11] (it asks for 5) to check out;
  • likewise, t7-Thread[13]'s check-in notify() only one thread t3-Thread[9];
  • t4-Thread[10] and t5-Thread[11] never have a chance to wake up and they may hang forever for the given scenario;





    References:

  •  


     
    Powered by ForumEasy © 2002-2022, All Rights Reserved. | Privacy Policy | Terms of Use
     
    Get your own forum today. It's easy and free.