Subject: sleep() in practice
Author: EricJ
In response to: wait() in practice
Posted on: 02/25/2007 04:42:06 AM
/**
*
* A sample code demonstrate how sleep() blocks process
*
*/
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);
ResourcePoolTester t7 = new ResourcePoolTester(pool, -9);
t6.start();
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{
Thread.sleep(1000); // wait for one second
}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 [10] is about to check out resources of: 4
Thread [11] is about to check out resources of: 5
Thread [12] is about to check in resources of: 6
Thread [13] is about to check in resources of: 9
Thread [8] wakes up with pool size = 1Thread [8] wakes up with pool size = 1Thread [8] wakes up with pool size = 1Thread [8] wakes up with pool size = 1Thread [8] wakes up with pool size = 1Thread [8] wakes up with pool size = 1...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;
once t2-Thread[8] is back after sleep of one second, it will loops forever because it withholds the monitor while sleeping and the check-in threads t6-Thread[12] and t7-Thread[13] have no chance to bring the resources into the pool.
>
> On 02/25/2007 04:17:48 AM EricJ wrote:
/**
*
* A sample code demonstrate how wait() works with notifyAll()
*
*/
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);
ResourcePoolTester t7 = new ResourcePoolTester(pool, -9);
t6.start();
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(1000); // wait for up to one second
}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 immediately. 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 immediately and return;
all threads have the fair chance to proceed.
References: