This is the mail archive of the java-patches@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: New threads regression tests


2000-03-23  Bryce McKinlay  <bryce@albatross.co.nz>

        * libjava.lang/Thread_Wait.java: New file.
        * libjava.lang/Thread_Sleep.java: New file.
        * libjava.lang/Thread_Monitor.java: New file.
        * libjava.lang/Thread_Wait.out: New file.
        * libjava.lang/Thread_Sleep.out: New file.
        * libjava.lang/Thread_Monitor.out: New file.
        * libjava.lang/Thread_Interrupt.java: New file.
        * libjava.lang/Thread_Wait_2.java: New file.
        * libjava.lang/Thread_Wait_2.out: New file.
        * libjava.lang/Thread_Wait_Interrupt.java: New file.
        * libjava.lang/Thread_Wait_Interrupt.out: New file.
        * libjava.lang/Thread_Interrupt.out: New file.
        * libjava.lang/Thread_Join.java: New file.
        * libjava.lang/Thread_Join.out: New file.
        * libjava.lang/Thread_Alive.java: New file.
        * libjava.lang/Thread_Alive.out: New file.

I'm checking these in.

regards

  [ bryce ]

// Test basic thread creation and wait/notify functionality.
// Origin: Bryce McKinlay <bryce@albatross.co.nz>

public class Thread_Wait implements Runnable
{
  public static void main(String args[])
  {
    new Thread_Wait();
  }
  
  public Thread_Wait()
  {
    System.out.println("creating thread");
    Thread t = new Thread(this);
    t.start();
    
    try
    {
      Thread.sleep(100);
    }
    catch (Exception x)
    {
      System.out.println("exception occured: " + x);
    }

    synchronized (this)
    {
      System.out.println("notifying other thread");
      notify();
    }
  }
  
  public void run()
  {
    System.out.println ("new thread running");
    synchronized (this)
    {
      try
      {
	wait();
      }
      catch (Exception x)
      {
        System.out.println("exception occured: " + x);
      }
    }    
    System.out.println ("thread notified okay");
  }
}
// Test the status of the isAlive() flag before, during, and after thread 
// execution. Check that thread's threadgroup is null after thread exits.
// Origin: Bryce McKinlay <bryce@albatross.co.nz>

public class Thread_Alive implements Runnable
{
  public static void main(String args[]) throws InterruptedException
  {
    Thread_Alive ta = new Thread_Alive();
    Thread t = new Thread(ta);
    System.out.println(t.isAlive());
    t.start();
    System.out.println(t.isAlive());

    Thread.sleep(100);
    
    synchronized (ta)
    {
      ta.notifyAll();
    }

    t.join();
    System.out.println(t.isAlive());
    
    try
    {
      t.start();
      System.out.println("Error: dead thread can be restarted.");
    }
    catch (IllegalThreadStateException x)
    {
      System.out.println ("ok");
    }

    System.out.println(t.getThreadGroup());
  }
  
  public synchronized void run()
  {
    try
    {
      wait();
    }
    catch (InterruptedException x) {}
  }
  
}
false
true
false
ok
null
// Test interrupt() behaviour on a thread in wait(), sleep(), and spinning 
// in a loop.
// Origin: Bryce McKinlay <bryce@albatross.co.nz>

class Waiter extends Thread
{
  public synchronized void run()
  {
    System.out.println ("wait()");
    try
    {
      wait();
      System.out.println("Error: wait() completed normally.");
    }
    catch (InterruptedException x)
    {
      if (isInterrupted() || interrupted()) 
        System.out.println("Error: interrupt flag is still set.");
    
    }
      System.out.println("interrupted - ok");
  }
}

class Sleeper extends Thread
{
  public void run()
  {
    System.out.println ("sleep()");
    try
    {
      sleep(2000);
      System.out.println("Error: sleep() completed normally.");
    }
    catch (InterruptedException x)
    {
      if (isInterrupted() || interrupted()) 
        System.out.println("Error: interrupt flag is still set.");
    
      System.out.println("interrupted - ok");
    }
  }
}

class Looper extends Thread
{
  public void run()
  {
    System.out.println ("Busy waiting");

    int count = 0;
    for (int i=0; i < 1000000; i++)
      {
        Thread.yield();
	count += 5;
	if (isInterrupted ())
	  break;
      }
    synchronized (this)
    {  
      if (interrupted ())
	{
	  System.out.println ("interrupted - ok");
	  if (isInterrupted () || interrupted ())
	    System.out.println("Error: interrupt flag is still set.");
	}
      else
	System.out.println ("Error: Busy wait was not interrupted.");          
    }
  }
}

class Joiner extends Thread
{
  public void run()
  {
    System.out.println("join()");
    try
    {
      join(2000);
      System.out.println("Error: join() completed normally??!");
    }
    catch (InterruptedException x)
    {
      if (isInterrupted() || interrupted()) 
        System.out.println("Error: interrupt flag is still set.");
    
      System.out.println("interrupted - ok");
    }

  }
}

public class Thread_Interrupt
{
  public static void main(String args[])
  {
    Waiter w = new Waiter();
    w.start ();
    sleep_and_interrupt (w);
    
    Sleeper s = new Sleeper();
    s.start ();
    sleep_and_interrupt (s);

    Looper l = new Looper ();
    l.start ();
    sleep_and_interrupt (l);

    Joiner j = new Joiner ();
    j.start ();
    sleep_and_interrupt (j);
  }
  
  public static void sleep_and_interrupt(Thread t)
  {
    try
    {
      Thread.sleep (250);
      t.interrupt ();
      long t1 = System.currentTimeMillis();
      t.join (5000);
      long time = System.currentTimeMillis() - t1;
      if (time > 2900)
        {
	  System.out.println ("Error: join() from main thread timed out");
	}
    }
    catch (InterruptedException x)
    {
      System.out.println("Error: main thread interrupted.");
    }
  }
}
wait()
interrupted - ok
sleep()
interrupted - ok
Busy waiting
interrupted - ok
join()
interrupted - ok
// Many threads join a single thread.
// Origin: Bryce McKinlay <bryce@albatross.co.nz>

class Sleeper implements Runnable
{
  int num = -1;
  
  public Sleeper(int num)
  {
    this.num = num;
  }
  
  public void run()
  {
    System.out.println("sleeping");
    try
    {
      Thread.sleep(500);
    }
    catch (InterruptedException x)
    {
      System.out.println("sleep() interrupted");
    }
    System.out.println("done");
  }
}

class Joiner implements Runnable
{
  Thread join_target;
  
  public Joiner(Thread t)
  {
    this.join_target = t;
  }
  
  public void run()
  {
    try
    {
      long start = System.currentTimeMillis();
      join_target.join(2000);
      if ((System.currentTimeMillis() - start) > 1900)
        System.out.println("Error: Join timed out");
      else
        System.out.println("ok");
    }
    catch (InterruptedException x)
    {
      System.out.println("join() interrupted");
    }
  }
  
}

public class Thread_Join
{
  public static void main(String[] args)
  {
    Thread primary = new Thread(new Sleeper(1));
    primary.start();
    for (int i=0; i < 10; i++)
    {
      Thread t = new Thread(new Joiner(primary));
      t.start();
    }
  }
}
sleeping
done
ok
ok
ok
ok
ok
ok
ok
ok
ok
ok
// Test that monitor locks work and are recursive.
// Origin: Bryce McKinlay <bryce@albatross.co.nz>

class T implements Runnable
{
  public int count = 0;
  Counter c;
  
  public T (Counter c)
  {
    this.c = c;
  }

  public void run()
  {
    while (true)
      {
        // NOTE: double-synchronization here.
	synchronized (c)
	{
	  if (c.getCount() <= 100000)
	    count++;
	  else
	    break;
	}
      }
  }
}

class Counter
{
  int i = 0;
  public synchronized int getCount ()
  {
    return ++i; 
  }
}

public class Thread_Monitor
{
  public static void main(String args[])
  {
    Counter c = new Counter();
    T t1 = new T(c);
    T t2 = new T(c);
    
    Thread th1 = new Thread(t1);
    Thread th2 = new Thread(t2);
    th1.start();
    th2.start();
    try
    {
      th1.join();
      th2.join();
    } 
    catch (InterruptedException x)
    {
      System.out.println("failed: Interrupted");
    }
    if (t1.count + t2.count == 100000)
      System.out.println ("ok");
    else
      System.out.println ("failed: total count incorrect");
  }
}
ok
// Test that Thread.sleep() works.
// Origin: Bryce McKinlay <bryce@albatross.co.nz>

public class Thread_Sleep
{
  public static void main(String args[])
  {
    try
    {
      long start = System.currentTimeMillis();
      System.out.println("sleeping");
      Thread.sleep(1000);
      long end = System.currentTimeMillis();
      if ((end - start) > 1100 || (end - start) < 990)
        System.out.println ("failed");
      else
	System.out.println("ok");
    }
    catch (InterruptedException x)
    {
      System.out.println("error: Thread interrupted.");
    }
  }
}
sleeping
ok
creating thread
new thread running
notifying other thread
thread notified okay
// Create many threads waiting on a monitor. Interrupt some of them. Do the 
// others wake up correctly with notify() and/or notifyAll()?
// Origin: Bryce McKinlay <bryce@albatross.co.nz>

import java.util.Vector;

class Waiter extends Thread
{
  Object monitor;
  int thread_num;
  boolean interrupted = false;
  boolean notified = false;

  Waiter (Object monitor, int thread_num)
  {
    this.monitor = monitor;
    this.thread_num = thread_num;
  }  
  
  public void run()
  {
    synchronized (monitor)
      {
	try
	{
	  monitor.wait();
	  notified = true;
	}
	catch (InterruptedException x)
	{
	  interrupted = true;
	}
      }
    
  }
}

public class Thread_Wait_2
{
  static Vector threads;
  static Object monitor = new Object();
  
  static final int NUM_THREADS = 10;
  
  public static void main(String args[])
  {
    
    
    try
    {
      makeThreads ();
      
      Thread.sleep(250);
      
      // Interrupt a few threads...
      Waiter i1 = (Waiter) threads.elementAt(3);
      Waiter i2 = (Waiter) threads.elementAt(4);
      Waiter i3 = (Waiter) threads.elementAt(9);
      i1.interrupt();
      i2.interrupt();
      i3.interrupt();
      
      // Call notify the exact number of times required to wake the remaining
      // threads.
      synchronized (monitor)
      {
	for (int i=0; i < NUM_THREADS -3 ; i++)
	{
	  monitor.notify ();
	}
      }
      
      joinAll();
      printStatus();
      
      // Repeat all the above, but use notifyAll() instead.
      makeThreads();

      Thread.sleep(250);
      
      // Interrupt a few threads...
      i1 = (Waiter) threads.elementAt(0);
      i2 = (Waiter) threads.elementAt(1);
      i3 = (Waiter) threads.elementAt(9);
      i1.interrupt();
      i2.interrupt();
      i3.interrupt();
      
      // Call notifyAll to wake the remaining threads.
      synchronized (monitor)
      {
        monitor.notifyAll ();
      }

      joinAll();
      printStatus();

    }
    catch (InterruptedException x)
    {
      System.out.println (x);
    }


  }
  
  static void makeThreads()
  {
    threads = new Vector(NUM_THREADS);
    
    for (int i=0; i < NUM_THREADS; i++)
      {
	Waiter w = new Waiter(monitor, i);
	w.start();
	threads.addElement(w);
      }
  }
  
  static void joinAll()
  {
    try
    {
      for (int i=0; i < threads.size(); i++)
	{
          Thread t = (Thread) threads.elementAt(i);
	  t.join();
	}
    }
    catch (InterruptedException x) {}
  }
  
  static void printStatus()
  {
    for (int i=0; i < threads.size(); i++)
      {
        Waiter w = (Waiter) threads.elementAt(i);
	if (w.interrupted)
	  System.out.println (i + " interrupted.");
	if (w.notified)
	  System.out.println (i + " notified.");
      }
  }
  
}
0 notified.
1 notified.
2 notified.
3 interrupted.
4 interrupted.
5 notified.
6 notified.
7 notified.
8 notified.
9 interrupted.
0 interrupted.
1 interrupted.
2 notified.
3 notified.
4 notified.
5 notified.
6 notified.
7 notified.
8 notified.
9 interrupted.
// Create two threads waiting on a monitor. Interrupt one of them. Does the 
// other wake up correctly?
// Origin: Bryce McKinlay <bryce@albatross.co.nz>

class Waiter extends Thread
{
  Object monitor;
  int thread_num;
  boolean interrupted = false;
  boolean notified = false; 

  Waiter (Object monitor, int thread_num)
  {
    this.monitor = monitor;
    this.thread_num = thread_num;
  }
  
  public void run()
  {
    synchronized (monitor)
      {
        System.out.println ("Thread waiting.");
	try
	{
	  long start = System.currentTimeMillis();
	  monitor.wait(1000);
	  long time = System.currentTimeMillis() - start;
	  if (time > 990)
	    System.out.println ("Error: wait on thread " + thread_num 
	                        + " timed out.");
	  else
	    notified = true;
	}
	catch (InterruptedException x)
	{
	  interrupted = true;
	}
      }
    
  }
}

public class Thread_Wait_Interrupt
{
  public static void main(String args[])
  {
    Object monitor = new Object();
    Waiter w1 = new Waiter(monitor, 1);
    Waiter w2 = new Waiter(monitor, 2);
    w1.start();
    w2.start();
    try
    {
      Thread.sleep(250);

      synchronized (monitor)
      {
	w1.interrupt();
	monitor.notify();
      }

      w1.join();
      w2.join();
      System.out.println("join ok");
      System.out.println("Thread 1 " + 
                         (w1.interrupted ? "interrupted ok" : "error"));
      System.out.println("Thread 2 " +
                         (w2.notified ? "notified ok" : "error"));

    }
    catch (InterruptedException x)
    {
      System.out.println (x);
    }
  }
}
Thread waiting.
Thread waiting.
join ok
Thread 1 interrupted ok
Thread 2 notified ok

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]