- Threads often need to share a common resource ie a file, with one
thread reading from the file while another thread writes to the file
- this is an example of a producer/consumer relationship
Race conditions
- race conditions occur when multiple, asynchronously executing
threads access the same object returning unexpected (wrong) results
- they can be avoided by synchronizing the methods which access the shared resource
/* Example of Synchronized Threads from "Java 2 Certification" by Jamie Jaworski p182 Example shows how synchronized methods and object locks are used to coordinate access to a common object by multiple threads. */
class Thread3 extends Thread { static String[] msg = { "Java", "is", "hot,", "aromatic,", "and", "invigorating." }; public static void main(String[] args) { Thread3 t1 = new Thread3("t1: "); Thread3 t2 = new Thread3("t2: "); t1.start(); t2.start(); boolean t1IsAlive = true; boolean t2IsAlive = true; do { if(t1IsAlive && !t1.isAlive()) { t1IsAlive = false; System.out.println("t1 is dead."); } if(t2IsAlive && !t2.isAlive()) { t2IsAlive = false; System.out.println("t2 is dead."); } } while(t1IsAlive || t2IsAlive); } public Thread3(String id) { super(id); } void randomWait() { try { Thread.currentThread().sleep((long)(3000*Math.random())); } catch(InterruptedException e) { System.out.println("Interrupted!"); } }
public synchronized void run() { SynchronizedOutput.displayList(getName(), msg); } }
class SynchronizedOutput {
// if the 'synchronized' keyword is removed, the message // is displayed in interleaved fashion public static synchronized void displayList(String name, String list[] ) { for(int i=0; i Thread3 t = (Thread3) Thread.currentThread(); t.randomWait(); System.out.println(name + list[i]); } } }
|