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 = 7Thread [8] returns with pool size = 5
Thread [9] wakes up with pool size = 5Thread [9] returns with pool size = 2
Thread [10] wakes up with pool size = 2Thread [10] is waiting with pool size = 2Thread [11] wakes up with pool size = 2Thread [11] is waiting with pool size = 2Thread [13] is about to check in resources of: 9
Thread [13] checked in with pool size = 11
Thread [10] wakes up with pool size = 11Thread [10] returns with pool size = 7
Thread [11] wakes up with pool size = 7Thread [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: