Week 7Concurrent Programming: Thread SynchronizationCS 180Sunil PrabhakarDepartment of Computer Science Purdue UniversityTuesday, December 8, 2009AnnouncementsExam 1 tonight 6:30 pm - 7:30 pmMTHW 2102Tuesday, December 8, 2009OutcomesUnderstand race conditionsCritical sections and mutual exclusionSynchronization mechanismsynchronized methods, block of codewait() and notify()Understand potential problemsbusy waitingdeadlocklivelock3Tuesday, December 8, 2009Thread SchedulingRememberOnce a thread is runnable it can be scheduled at any timeIt is hard to predict the actual orderingWith multiple threads, we must ensure that any possible interleaving of threads would still be a correct execution4Tuesday, December 8, 2009Race ConditionsIf the result of a computation changes depending upon the actual ordering of threads we call it a race condition.Can occur even with very simple concurrent programs.Consider a program that simply increments a single variable, count 100000 timesthe task is divided among multiple threads5Tuesday, December 8, 2009Race Example6public class RaceCondition extends Thread {private static int counter = 0;public static final int THREADS = 4;public static final int COUNT = 10000000; public static void main(String[] args){RaceCondition[] threads = new RaceCondition[THREADS];for(int i=0;i<THREADS;i++) {threads[i] = new RaceCondition();threads[i].start();}try{for(int i=0;i<THREADS;i++)threads[i].join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(“Counter: “ + counter);}public void run(){for(int i=0;i<COUNT/THREADS;i++)counter++;}}Tuesday, December 8, 2009RaceWithout multiple threads, always correct.With multiple threads, often incorrect!Why?multiple threads modifying the same valuecounter++ is not atomicAtomic operationsA java statement translates to multiple machine level statementsthe thread can be swapped in the middle of these machine level statements7Tuesday, December 8, 2009CPUThe memory hierarchy8ALUCacheCache (MB)RegistersMain Memory (GB)SpeedSizeCostTuesday, December 8, 2009Multi Core possibility9Cache (MB)CoreALUCacheRegistersMain Memory (GB)CoreALUCacheRegistersCPUTuesday, December 8, 2009CPUMulti Core possibility 210Cache (MB)Main Memory (GB)CoreALURegistersCoreALURegistersTuesday, December 8, 2009CPUMulti CPU possibility11CPUALUCacheRegistersMain Memory (GB)ALUCacheRegistersCache (MB)Cache (MB)ALUCacheRegistersProgram DataTuesday, December 8, 2009Atomic operations and CachingData is operated on in ALUsregister = count;register++;count = register;Thus if a thread is swapped out just before the last statement, and another thread swapped in, then we have a “lost update”The memory hierarchy caches data values.If multiple threads are using some data, it gets copied into multiple cachesthis can cause different threads to not see all changes made by other threads!12Tuesday, December 8, 2009Shared mutable stateHow do we ensure correct behavior?Many problems of synchronization can be traced to data that is concurrently read and written by multiple threadsshared mutable stateif no thread writes -- no problemsFor example, the variable count is shared mutable state.Only one thread should modify at a given time, and no thread should read the value during this time.13Tuesday, December 8, 2009Critical SectionA section of code that should not be accessed by multiple threads concurrentlyWe need to guarantee mutual exclusion in these sectionsJava solution:use a lock that only one thread holds at a timealso called a monitorany object can be locked14Tuesday, December 8, 2009Synchronized The synchronized keyword can be used to declare a method or block of code as a critical sectioni.e., only one thread can be executing any statements in that method or block of code.15public synchronized int methodA(){. . .//Critical section }public int methodA(){. . .synchronized (someObject) {. . . //Critical section}}Tuesday, December 8, 2009Method vs. block of codeWhen synchronized is used with a block of code, we explicitly specify what object should be used for locking;can arbitrarily limit the critical sectioncan have independent locks for different code.A synchronized method implicitly locks the object (this) on which the method is calledthe class, in the case of static methods16Tuesday, December 8, 2009(No) Race Condition17public class NoRaceCondition extends Thread {private static int counter = 0;public static final int THREADS = 4;public static Object lock = new Object();public static final int COUNT = 1000000; public static void main(String[] args){NoRaceCondition[] threads = new NoRaceCondition[THREADS];for(int i=0;i<THREADS;i++) {threads[i] = new NoRaceCondition();threads[i].start();}try{for(int i=0;i<THREADS;i++)threads[i].join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(“Counter: “ + counter);}public void run(){for(int i=0;i<COUNT/THREADS;i++){synchronized(NoRaceCondition.lock){counter++;}}}}Note: lock is static.Note: not entire method or for loop!Tuesday, December 8, 2009SynchronizationAny code that is synchronized can only be executed by a thread that holds the appropriate lockOnly one thread can hold the lock for a given objectAny changes made in a critical section will be visible to all threads once they get the lock (ensured by Java)18Tuesday, December 8, 2009AnnouncementsNo class on MondayNo labs next week19Tuesday, December 8, 2009Producer-ConsumerA very common scenarioa producer process creates dataa consumer process processes data (and deletes it)e.g., networking, unix pipes, device driversA shared data structure (buffer) is used to hold data before processinglimited sizeif empty -- consumer waitsif full -- produce waits20Tuesday, December 8, 200921import java.util.*;public class ProducerConsumer extends Thread{ private static Buffer buffer = new Buffer(); private boolean isConsumer;public ProducerConsumer(boolean isC){isConsumer=isC;}public static void main ( String[] args ) { ProducerConsumer consumer = new ProducerConsumer(true);ProducerConsumer producer = new ProducerConsumer(false);consumer.start();producer.start();try{consumer.join();producer.join();} catch (InterruptedException e) {e.printStackTrace(); }}// run method}Producer-ConsumerTuesday, December 8, 200922public void
View Full Document