// SemaphoreTest.java

// Shows how to create a Semaphore (a switch) that permits
// simultaneous access to a resource by no more than n threads. 

// By Kip Irvine
// Updated 9/11/03

class Semaphore 
{
	static final int MAX_COUNT = 2;			// maximum simultaneous connections
	
	// blocks if another thread owns the Semaphore
	public synchronized void obtain( int threadNum ) throws InterruptedException
	{
		System.out.println( "Thread " + threadNum + " requesting the semaphore:" );
        while( count >= MAX_COUNT )
          	this.wait();
          	
        count++;					// increase connected count
        System.out.println( "...Semaphore obtained by Thread " + threadNum );
	}
	
	public synchronized void release( int threadNum )
	{
		System.out.println( "...Semaphore released by Thread " + threadNum );
		count--;						// decrease connected count
		this.notifyAll( );
	}		

	private int count = 0;
}

class SemaphoreTester extends Thread
{
	// must be static so all threads will use same Semaphore
	static Semaphore semaphore = new Semaphore( );
	private static int count = 0;
	private int testerID = count++;

	public void run( )
	{
		try {
			// first attempt to get the semaphore
			semaphore.obtain( testerID );
			sleep( 1000 );	
			semaphore.release( testerID );

			// repeat a second time
			semaphore.obtain( testerID );
			sleep( 1000 );	
			semaphore.release( testerID );

		} 
		catch( InterruptedException e ) 
		{
			return;
		}
	}

	public static void main( String args[] )
	{
		Thread t1 = new SemaphoreTester( );
		Thread t2 = new SemaphoreTester( );
		Thread t3 = new SemaphoreTester( );
		t1.start( );
		t2.start( );
		t3.start( );		
	}

}
