00001 00002 /** 00003 * The class <code>T2</code> implements <code>Runnable</code> class. 00004 * Instance of the <code>T2</code> prints out its signature 00005 * until it gets stopped. It also creates a charged particle pair 00006 * in associated <code>JPWorld</code> context. 00007 * 00008 * @author Mikica B Kocic 00009 */ 00010 public class T2 implements Runnable 00011 { 00012 private String signature = "T2: Thread 2"; 00013 00014 /** 00015 * Indicates if thread is (or should be) running 00016 */ 00017 private volatile boolean running = false; 00018 00019 /** 00020 * Indicates that thread is active and not paused 00021 */ 00022 private volatile boolean active = false; 00023 00024 /** 00025 * Instance of the main thread. 00026 */ 00027 private volatile Thread mainThread = null; 00028 00029 /** 00030 * Sleep interval for thread in millis. 00031 */ 00032 private int sleepIntervalMillis; 00033 00034 /** 00035 * Parent where println() messages are directed to. 00036 */ 00037 protected JPWorld parent; 00038 00039 /** 00040 * Creates a new instance of T1. 00041 * 00042 * @param parent owner of the thread 00043 * @param sleepIntervalSec sleep interval in seconds 00044 */ 00045 public T2( JPWorld parent, float sleepIntervalSec ) 00046 { 00047 this.parent = parent; 00048 this.sleepIntervalMillis = (int)( sleepIntervalSec * 1000f ); 00049 } 00050 00051 /** 00052 * Starts the thread 00053 */ 00054 public void startThread () 00055 { 00056 synchronized( this ) 00057 { 00058 if ( mainThread != null ) { 00059 return; // Allow only single thread per instance 00060 } 00061 00062 running = true; 00063 active = true; 00064 mainThread = new Thread( this ); 00065 mainThread.start (); 00066 } 00067 } 00068 00069 /** 00070 * Stops the thread 00071 */ 00072 public void stopThread () 00073 { 00074 synchronized( this ) 00075 { 00076 running = false; 00077 active = false; 00078 this.notifyAll (); 00079 } 00080 } 00081 00082 /** 00083 * Disables (pauses) the thread 00084 */ 00085 public void disableThread () 00086 { 00087 synchronized( this ) 00088 { 00089 active = false; 00090 this.notifyAll (); 00091 } 00092 } 00093 00094 /** 00095 * Enables the thread after paused 00096 */ 00097 public void enableThread () 00098 { 00099 synchronized( this ) 00100 { 00101 active = true; 00102 this.notifyAll (); 00103 } 00104 } 00105 00106 /** 00107 * Interruptible sleep (replacement for <code>Thread.sleep</code>). 00108 * 00109 * @param millis - the length of time to sleep in milliseconds. 00110 */ 00111 public void interruptibleSleep( long millis ) 00112 { 00113 synchronized( this ) 00114 { 00115 try { 00116 this.wait( millis ); 00117 } 00118 catch( InterruptedException ie ) { 00119 running = false; // signals thread to quit 00120 } 00121 } 00122 } 00123 00124 /** 00125 * Prints thread's own signature and creates a pair of particles in belonging 00126 * <code>JPWorld</code>'s context every <code>sleepItervalMillis</code>. 00127 */ 00128 @Override 00129 public void run () 00130 { 00131 while( running ) 00132 { 00133 while( running && active ) 00134 { 00135 parent.println( signature ); 00136 00137 parent.createPairOfChargedParticles( 1, 10.0 + Math.random () * 5.0 ); 00138 00139 interruptibleSleep( sleepIntervalMillis ); 00140 } 00141 00142 while( running && ! active ) 00143 { 00144 interruptibleSleep( sleepIntervalMillis ); 00145 } 00146 } 00147 00148 synchronized( this ) 00149 { 00150 running = false; 00151 active = false; 00152 mainThread = null; 00153 } 00154 } 00155 }