Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CITS3213: CONCURRENT PROGRAMMING Java Synchronization Concurrency in Java Synchronization and mutual exclusion via a variant of monitors Java includes support for concurrency based principally on dynamically created threads, shared variables and a variant of monitors. • Each object acts like a monitor • Only one thread may be running within the “synchronized” methods of each object Threads are created by: • Constructing Thread objects • This thread holds the lock on the object • Then, calling the start() method to start the thread • Other threads will wait until they can acquire the lock • The new thread executes whatever code is in a method called run(). • A thread already holding a lock may call other synchronized methods on the object • The run() method may be in the Thread object (via subclassing) • Or in a Runnable object passed to the thread constructor. • Threads may hold locks on many objects at once (beware of deadlocks!) • The thread completes when the run() method returns. • Unsynchronized methods are also allowed • The original thread continues concurrently after the call to start(). • No condition variables (unlike standard monitors) • The whole program ends when all threads complete (including main). • Instead wait() and notifyAll() suspend and resume threads on a particular object • Waiting for a condition is achieved by repeatedly calling wait(), testing the condition each time 1 2 Creating Threads: Subclassing Thread Creating Threads: Implementing Runnable public class Example1{ public class Example2 { public static void main(String args[]) { MyThread thread1=new MyThread(); MyThread thread2=new MyThread(); thread1.start(); thread2.start(); } public static void main(String args[]) { Thread thread1=new Thread(new MyThread()); Thread thread2=new Thread(new MyThread()); thread1.start(); thread2.start(); } } } class MyThread extends Thread { static String message[] = {"Java", "is","..."}; class MyThread implements Runnable { static String message[] = {"Java", "is","..."}; public void run() { for(int i=0;i<message.length;i++){ randomWait(); System.out.println(message[i]); } } void randomWait(){ try{ sleep((int)(1000*Math.random())); } catch (InterruptedException x) {} } public void run() { for(int i=0;i<message.length;i++){ randomWait(); System.out.println(message[i]); } } void randomWait(){ try { sleep((int)(1000*Math.random())); } catch (InterruptedException x) { } } } } 3 4 Synchronization: methods Synchronization: wait and notifyAll • So far our threads are allowed to both be running in the same object • When a thread holding the lock on an object needs to wait for some condition, it calls wait() • In many cases we need some kind of mutual exclusion • There are no condition variables, so the usual pattern is to call notifyAll() whenever a change occurs that might be what a thread is waiting for. • Java uses a variant of monitors • Only one thread can be in the “synchronized” methods of each object • Then, each waiting thread should have a loop that repeatedly waits, checking a condition each time. (See following example.) public class Counter { private int count=0; • Just like standard monitors, threads release mutual exclusion (on all objects) when they wait. • Only threads that have mutual exclusion on an object may wait or notify on that object. public synchronized void inc() { count = count+1; } • The notify() function is NOT recommended: no guarantee that the thread is scheduled immediately. public synchronized void dec() { count = count-1; } public int getCount() { return count; } • Unlike standard monitors, threads are not woken in FIFO order. // not synchronized } 5 6 Producer-Consumer in Java Producer-Consumer in Java public class Buffer { private static final int N = 5; private int[] B = new int[N]; private int InPtr=0, OutPtr=0; private int Count=0; public synchronized void append(int value) { while (Count==N) { try { wait(); } catch (InterruptedException e) {} } B[InPtr] = value; InPtr = (InPtr+1) % N; Count = Count+1; notifyAll(); } // class Buffer continued from page 1. public synchronized int take () { while (Count==0) { try { wait(); } catch (InterruptedException e) {} } int I = B[OutPtr]; OutPtr = (OutPtr+1) % N; Count = Count-1; notifyAll(); return I; } } // class Buffer continued on page 2. 7 8 Producer-Consumer in Java public class Producer extends Thread { private Buffer buffer; Producer-Consumer in Java public class Consumer extends Thread { private Buffer buffer; public Producer(Buffer c) { buffer = c; } public Consumer(Buffer c) { buffer = c; } public void run() { for (int i = 0; i < 100; i++) { buffer.append(i); System.out.println("Produced:" +i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } public void run() { for (int i = 0; i < 100; i++) { int v = buffer.take(); System.out.println("Consumed: " + v); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } } } 9 Producer-Consumer in Java public class ProducerConsumerTest { public static void main(String[] args) { Buffer buf = new Buffer(); Producer p1 = new Producer(buf); Consumer c1 = new Consumer(buf); p1.start(); c1.start(); } } 11 10