/**	Statics.java
 *
 * Illustrates that statics and each instance have different monitors.
 *	by Mark Weiss
 */
class Foo
{
    synchronized public static void staticMethod( ) throws InterruptedException
    {
        System.out.println( "Entering static method" );
        Thread.sleep( 60000 );
        System.out.println( "Leaving static method" );
    }
    
    synchronized public void instanceMethod( ) throws InterruptedException
    {
        System.out.println( "Entering instance method " + this );
        Thread.sleep( 2000 );
        System.out.println( "Leaving instance method " + this );
    }
    
    private int id = count++;
    private static int count = 1;
    
    public String toString( )
    {
        return "Foo #" + id;
    }
}

class MonitorThread extends Thread
{
    public MonitorThread( Foo f )
    {
        this.f = f;
    }
    
    public void run( )
    {
        try
        {
            f.instanceMethod( );
            f.staticMethod( );
        }
        catch( InterruptedException e )
        {
        }
    }
    
    private Foo f;
}

class StaticsAndThreads 
{
    public static void main( String[] args )
    {
        Foo f1 = new Foo( );
        Foo f2 = new Foo( );
        Foo f3 = new Foo( );
        
        Thread t1 = new MonitorThread( f1 );
        Thread t2 = new MonitorThread( f2 );
        Thread t3 = new MonitorThread( f3 );
 
        t1.start( );                 
        t2.start( );
        t3.start( );
    }
        
}
