/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/licenses/publicdomain
 * Other contributors include Andrew Wright, Jeffrey Hayes, 
 * Pat Fisher, Mike Judd. 
 */

import junit.framework.*;
import java.util.*;
import java.util.concurrent.*;
import java.io.*;

public class SemaphoreTest extends JSR166TestCase {
    public static void main(String[] args) {
	junit.textui.TestRunner.run (suite());	
    }
    public static Test suite() {
	return new TestSuite(SemaphoreTest.class);
    }

    /**
     * Subclass to expose protected methods
     */
    static class PublicSemaphore extends Semaphore {
        PublicSemaphore(int p, boolean f) { super(p, f); }
        public Collection<Thread> getQueuedThreads() { 
            return super.getQueuedThreads(); 
        }
        public void reducePermits(int p) { 
            super.reducePermits(p);
        }
    }

    /**
     * A runnable calling acquire
     */
    class InterruptibleLockRunnable implements Runnable {
        final Semaphore lock;
        InterruptibleLockRunnable(Semaphore l) { lock = l; }
        public void run() {
            try {
                lock.acquire();
            } catch(InterruptedException success){}
        }
    }


    /**
     * A runnable calling acquire that expects to be
     * interrupted
     */
    class InterruptedLockRunnable implements Runnable {
        final Semaphore lock;
        InterruptedLockRunnable(Semaphore l) { lock = l; }
        public void run() {
            try {
                lock.acquire();
                threadShouldThrow();
            } catch(InterruptedException success){}
        }
    }

    /**
     * Zero, negative, and positive initial values are allowed in constructor
     */
    public void testConstructor() {
        Semaphore s0 = new Semaphore(0, false);
        assertEquals(0, s0.availablePermits());
        assertFalse(s0.isFair());
        Semaphore s1 = new Semaphore(-1, false);
        assertEquals(-1, s1.availablePermits());
        assertFalse(s1.isFair());
        Semaphore s2 = new Semaphore(-1, false);
        assertEquals(-1, s2.availablePermits());
        assertFalse(s2.isFair());
    }

    /**
     * Constructor without fairness argument behaves as nonfair
     */
    public void testConstructor2() {
        Semaphore s0 = new Semaphore(0);
        assertEquals(0, s0.availablePermits());
        assertFalse(s0.isFair());
        Semaphore s1 = new Semaphore(-1);
        assertEquals(-1, s1.availablePermits());
        assertFalse(s1.isFair());
        Semaphore s2 = new Semaphore(-1);
        assertEquals(-1, s2.availablePermits());
        assertFalse(s2.isFair());
    }

    /**
     * tryAcquire succeeds when sufficient permits, else fails
     */
    public void testTryAcquireInSameThread() {
        Semaphore s = new Semaphore(2, false);
        assertEquals(2, s.availablePermits());
        assertTrue(s.tryAcquire());
        assertTrue(s.tryAcquire());
        assertEquals(0, s.availablePermits());
        assertFalse(s.tryAcquire());
    }

    /**
     * Acquire and release of semaphore succeed if initially available
     */
    public void testAcquireReleaseInSameThread() {
        Semaphore s = new Semaphore(1, false);
        try {
            s.acquire();
            s.release();
            s.acquire();
            s.release();
            s.acquire();
            s.release();
            s.acquire();
            s.release();
            s.acquire();
            s.release();
            assertEquals(1, s.availablePermits());
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * Uninterruptible acquire and release of semaphore succeed if
     * initially available
     */
    public void testAcquireUninterruptiblyReleaseInSameThread() {
        Semaphore s = new Semaphore(1, false);
        try {
            s.acquireUninterruptibly();
            s.release();
            s.acquireUninterruptibly();
            s.release();
            s.acquireUninterruptibly();
            s.release();
            s.acquireUninterruptibly();
            s.release();
            s.acquireUninterruptibly();
            s.release();
            assertEquals(1, s.availablePermits());
	} finally {
        }
    }

    /**
     * Timed Acquire and release of semaphore succeed if
     * initially available
     */
    public void testTimedAcquireReleaseInSameThread() {
        Semaphore s = new Semaphore(1, false);
        try {
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertEquals(1, s.availablePermits());
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * A release in one thread enables an acquire in another thread
     */
    public void testAcquireReleaseInDifferentThreads() {
        final Semaphore s = new Semaphore(0, false);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.acquire();
                        s.release();
                        s.release();
                        s.acquire();
		    } catch(InterruptedException ie){
                        threadUnexpectedException();
                    }
		}
	    });
        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            s.release();
            s.release();
            s.acquire();
            s.acquire();
            s.release();
            t.join();
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * A release in one thread enables an uninterruptible acquire in another thread
     */
    public void testUninterruptibleAcquireReleaseInDifferentThreads() {
        final Semaphore s = new Semaphore(0, false);
	Thread t = new Thread(new Runnable() {
		public void run() {
                    s.acquireUninterruptibly();
                    s.release();
                    s.release();
                    s.acquireUninterruptibly();
		}
	    });
        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            s.release();
            s.release();
            s.acquireUninterruptibly();
            s.acquireUninterruptibly();
            s.release();
            t.join();
	} catch( InterruptedException e){
            unexpectedException();
        }
    }


    /**
     *  A release in one thread enables a timed acquire in another thread
     */
    public void testTimedAcquireReleaseInDifferentThreads() {
        final Semaphore s = new Semaphore(1, false);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
                        s.release();
                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                        s.release();
                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));

		    } catch(InterruptedException ie){
                        threadUnexpectedException();
                    }
		}
	    });
        try {
            t.start();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            s.release();
            t.join();
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * A waiting acquire blocks interruptibly
     */
    public void testAcquire_InterruptedException() {
	final Semaphore s = new Semaphore(0, false);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.acquire();
			threadShouldThrow();
		    } catch(InterruptedException success){}
		}
	    });
	t.start();
	try {
	    Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
        } catch(InterruptedException e){
            unexpectedException();
        }
    }
    
    /**
     *  A waiting timed acquire blocks interruptibly
     */
    public void testTryAcquire_InterruptedException() {
	final Semaphore s = new Semaphore(0, false);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
			threadShouldThrow();
		    } catch(InterruptedException success){
                    }
		}
	    });
	t.start();
	try {
	    Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
        } catch(InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * hasQueuedThreads reports whether there are waiting threads
     */
    public void testHasQueuedThreads() { 
	final Semaphore lock = new Semaphore(1, false);
        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
        try {
            assertFalse(lock.hasQueuedThreads());
            lock.acquireUninterruptibly();
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(lock.hasQueuedThreads());
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(lock.hasQueuedThreads());
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(lock.hasQueuedThreads());
            lock.release();
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(lock.hasQueuedThreads());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * getQueueLength reports number of waiting threads
     */
    public void testGetQueueLength() { 
	final Semaphore lock = new Semaphore(1, false);
        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
        try {
            assertEquals(0, lock.getQueueLength());
            lock.acquireUninterruptibly();
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(1, lock.getQueueLength());
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(2, lock.getQueueLength());
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(1, lock.getQueueLength());
            lock.release();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(0, lock.getQueueLength());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * getQueuedThreads includes waiting threads
     */
    public void testGetQueuedThreads() { 
	final PublicSemaphore lock = new PublicSemaphore(1, false);
        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
        try {
            assertTrue(lock.getQueuedThreads().isEmpty());
            lock.acquireUninterruptibly();
            assertTrue(lock.getQueuedThreads().isEmpty());
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(lock.getQueuedThreads().contains(t1));
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(lock.getQueuedThreads().contains(t1));
            assertTrue(lock.getQueuedThreads().contains(t2));
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(lock.getQueuedThreads().contains(t1));
            assertTrue(lock.getQueuedThreads().contains(t2));
            lock.release();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(lock.getQueuedThreads().isEmpty());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * drainPermits reports and removes given number of permits
     */
    public void testDrainPermits() {
        Semaphore s = new Semaphore(0, false);
        assertEquals(0, s.availablePermits());
        assertEquals(0, s.drainPermits());
        s.release(10);
        assertEquals(10, s.availablePermits());
        assertEquals(10, s.drainPermits());
        assertEquals(0, s.availablePermits());
        assertEquals(0, s.drainPermits());
    }

    /**
     * reducePermits reduces number of permits
     */
    public void testReducePermits() {
        PublicSemaphore s = new PublicSemaphore(10, false);
        assertEquals(10, s.availablePermits());
        s.reducePermits(1);
        assertEquals(9, s.availablePermits());
        s.reducePermits(10);
        assertEquals(-1, s.availablePermits());
    }

    /**
     * a deserialized serialized semaphore has same number of permits
     */
    public void testSerialization() {
        Semaphore l = new Semaphore(3, false);
        try {
            l.acquire();
            l.release();
            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
            out.writeObject(l);
            out.close();

            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
            Semaphore r = (Semaphore) in.readObject();
            assertEquals(3, r.availablePermits());
            assertFalse(r.isFair());
            r.acquire();
            r.release();
        } catch(Exception e){
            unexpectedException();
        }
    }


    /**
     * Zero, negative, and positive initial values are allowed in constructor
     */
    public void testConstructor_fair() {
        Semaphore s0 = new Semaphore(0, true);
        assertEquals(0, s0.availablePermits());
        assertTrue(s0.isFair());
        Semaphore s1 = new Semaphore(-1, true);
        assertEquals(-1, s1.availablePermits());
        Semaphore s2 = new Semaphore(-1, true);
        assertEquals(-1, s2.availablePermits());
    }

    /**
     * tryAcquire succeeds when sufficient permits, else fails
     */
    public void testTryAcquireInSameThread_fair() {
        Semaphore s = new Semaphore(2, true);
        assertEquals(2, s.availablePermits());
        assertTrue(s.tryAcquire());
        assertTrue(s.tryAcquire());
        assertEquals(0, s.availablePermits());
        assertFalse(s.tryAcquire());
    }

    /**
     * tryAcquire(n) succeeds when sufficient permits, else fails
     */
    public void testTryAcquireNInSameThread_fair() {
        Semaphore s = new Semaphore(2, true);
        assertEquals(2, s.availablePermits());
        assertTrue(s.tryAcquire(2));
        assertEquals(0, s.availablePermits());
        assertFalse(s.tryAcquire());
    }

    /**
     * Acquire and release of semaphore succeed if initially available
     */
    public void testAcquireReleaseInSameThread_fair() {
        Semaphore s = new Semaphore(1, true);
        try {
            s.acquire();
            s.release();
            s.acquire();
            s.release();
            s.acquire();
            s.release();
            s.acquire();
            s.release();
            s.acquire();
            s.release();
            assertEquals(1, s.availablePermits());
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * Acquire(n) and release(n) of semaphore succeed if initially available
     */
    public void testAcquireReleaseNInSameThread_fair() {
        Semaphore s = new Semaphore(1, true);
        try {
            s.release(1);
            s.acquire(1);
            s.release(2);
            s.acquire(2);
            s.release(3);
            s.acquire(3);
            s.release(4);
            s.acquire(4);
            s.release(5);
            s.acquire(5);
            assertEquals(1, s.availablePermits());
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * Acquire(n) and release(n) of semaphore succeed if initially available
     */
    public void testAcquireUninterruptiblyReleaseNInSameThread_fair() {
        Semaphore s = new Semaphore(1, true);
        try {
            s.release(1);
            s.acquireUninterruptibly(1);
            s.release(2);
            s.acquireUninterruptibly(2);
            s.release(3);
            s.acquireUninterruptibly(3);
            s.release(4);
            s.acquireUninterruptibly(4);
            s.release(5);
            s.acquireUninterruptibly(5);
            assertEquals(1, s.availablePermits());
	} finally {
        }
    }

    /**
     * release(n) in one thread enables timed acquire(n) in another thread
     */
    public void testTimedAcquireReleaseNInSameThread_fair() {
        Semaphore s = new Semaphore(1, true);
        try {
            s.release(1);
            assertTrue(s.tryAcquire(1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release(2);
            assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release(3);
            assertTrue(s.tryAcquire(3, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release(4);
            assertTrue(s.tryAcquire(4, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release(5);
            assertTrue(s.tryAcquire(5, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            assertEquals(1, s.availablePermits());
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * release in one thread enables timed acquire in another thread
     */
    public void testTimedAcquireReleaseInSameThread_fair() {
        Semaphore s = new Semaphore(1, true);
        try {
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release();
            assertEquals(1, s.availablePermits());
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * A release in one thread enables an acquire in another thread
     */
    public void testAcquireReleaseInDifferentThreads_fair() {
        final Semaphore s = new Semaphore(0, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.acquire();
                        s.acquire();
                        s.acquire();
                        s.acquire();
		    } catch(InterruptedException ie){
                        threadUnexpectedException();
                    }
		}
	    });
        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            s.release();
            s.release();
            s.release();
            s.release();
            s.release();
            s.release();
            t.join();
            assertEquals(2, s.availablePermits());
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * release(n) in one thread enables acquire(n) in another thread
     */
    public void testAcquireReleaseNInDifferentThreads_fair() {
        final Semaphore s = new Semaphore(0, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.acquire();
                        s.release(2);
                        s.acquire();
		    } catch(InterruptedException ie){
                        threadUnexpectedException();
                    }
		}
	    });
        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            s.release(2);
            s.acquire(2);
            s.release(1);
            t.join();
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * release(n) in one thread enables acquire(n) in another thread
     */
    public void testAcquireReleaseNInDifferentThreads_fair2() {
        final Semaphore s = new Semaphore(0, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
                        s.acquire(2);
                        s.acquire(2);
                        s.release(4);
		    } catch(InterruptedException ie){
                        threadUnexpectedException();
                    }
		}
	    });
        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            s.release(6);
            s.acquire(2);
            s.acquire(2);
            s.release(2);
            t.join();
	} catch( InterruptedException e){
            unexpectedException();
        }
    }





    /**
     * release in one thread enables timed acquire in another thread
     */
    public void testTimedAcquireReleaseInDifferentThreads_fair() {
        final Semaphore s = new Semaphore(1, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));

		    } catch(InterruptedException ie){
                        threadUnexpectedException();
                    }
		}
	    });
	t.start();
        try {
            s.release();
            s.release();
            s.release();
            s.release();
            s.release();
            t.join();
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * release(n) in one thread enables timed acquire(n) in another thread
     */
    public void testTimedAcquireReleaseNInDifferentThreads_fair() {
        final Semaphore s = new Semaphore(2, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
                        threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                        s.release(2);
                        threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                        s.release(2);
		    } catch(InterruptedException ie){
                        threadUnexpectedException();
                    }
		}
	    });
	t.start();
        try {
            assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release(2);
            assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            s.release(2);
            t.join();
	} catch( InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * A waiting acquire blocks interruptibly
     */
    public void testAcquire_InterruptedException_fair() {
	final Semaphore s = new Semaphore(0, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.acquire();
			threadShouldThrow();
		    } catch(InterruptedException success){}
		}
	    });
	t.start();
	try {
	    Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
        } catch(InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * A waiting acquire(n) blocks interruptibly
     */
    public void testAcquireN_InterruptedException_fair() {
	final Semaphore s = new Semaphore(2, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.acquire(3);
			threadShouldThrow();
		    } catch(InterruptedException success){}
		}
	    });
	t.start();
	try {
	    Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
        } catch(InterruptedException e){
            unexpectedException();
        }
    }
    
    /**
     *  A waiting tryAcquire blocks interruptibly
     */
    public void testTryAcquire_InterruptedException_fair() {
	final Semaphore s = new Semaphore(0, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
			threadShouldThrow();
		    } catch(InterruptedException success){
                    }
		}
	    });
	t.start();
	try {
	    Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
        } catch(InterruptedException e){
            unexpectedException();
        }
    }

    /**
     *  A waiting tryAcquire(n) blocks interruptibly
     */
    public void testTryAcquireN_InterruptedException_fair() {
	final Semaphore s = new Semaphore(1, true);
	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
			s.tryAcquire(4, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
			threadShouldThrow();
		    } catch(InterruptedException success){
                    }
		}
	    });
	t.start();
	try {
	    Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
        } catch(InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * getQueueLength reports number of waiting threads
     */
    public void testGetQueueLength_fair() { 
	final Semaphore lock = new Semaphore(1, true);
        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
        try {
            assertEquals(0, lock.getQueueLength());
            lock.acquireUninterruptibly();
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(1, lock.getQueueLength());
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(2, lock.getQueueLength());
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(1, lock.getQueueLength());
            lock.release();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(0, lock.getQueueLength());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 


    /**
     * a deserialized serialized semaphore has same number of permits
     */
    public void testSerialization_fair() {
        Semaphore l = new Semaphore(3, true);

        try {
            l.acquire();
            l.release();
            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
            out.writeObject(l);
            out.close();

            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
            Semaphore r = (Semaphore) in.readObject();
            assertEquals(3, r.availablePermits());
            assertTrue(r.isFair());
            r.acquire();
            r.release();
        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * toString indicates current number of permits
     */
    public void testToString() {
        Semaphore s = new Semaphore(0);
        String us = s.toString();
        assertTrue(us.indexOf("Permits = 0") >= 0);
        s.release();
        String s1 = s.toString();
        assertTrue(s1.indexOf("Permits = 1") >= 0);
        s.release();
        String s2 = s.toString();
        assertTrue(s2.indexOf("Permits = 2") >= 0);
    }

}
