Concurrent Programming u Traditional programs do one thing

  • Slides: 22
Download presentation
Concurrent Programming u Traditional programs do one thing at a time. u Concurrent programs

Concurrent Programming u Traditional programs do one thing at a time. u Concurrent programs do several things at once. u Why do this? – exploit parallel hardware – defer work (“to-do list”) – interface to slow device (disk, printer, net) – interface with person COS 461 – handle many network clients at once Fall 1997

Expressing Concurrency u Use a thread for each concurrent activity. u Multiple threads can

Expressing Concurrency u Use a thread for each concurrent activity. u Multiple threads can run within a single program. – appear to run at the same time – really, they take turns running – scheduling happens automatically u. A sequential program is a program with one thread in it. COS 461 Fall 1997

Starting a Thread: Method 1 class My. Thread extends java. lang. Thread { …

Starting a Thread: Method 1 class My. Thread extends java. lang. Thread { … public void run() { // code you want the thread to execute } } // start a thread My. Thread t = new My. Thread(args); t. start(); COS 461 Fall 1997

Starting a Thread: Method 2 class My. Class implements java. lang. Runnable { …

Starting a Thread: Method 2 class My. Class implements java. lang. Runnable { … public void run() { // code you want the thread to execute } } // start a thread My. Class m = new My. Class(args) Thread t = new Thread(m); t. start(); COS 461 Fall 1997

Other Thread Operations u Thread. current. Thread gets the identity of the currently-running thread.

Other Thread Operations u Thread. current. Thread gets the identity of the currently-running thread. u Thread. sleep(millis) puts the calling thread to sleep for milliseconds. u t. stop() kills thread t. u thread suicide: Thread. current. Thread. stop(); – or return from run COS 461 Fall 1997

Shared Memory u Threads in the same program share memory. – Good: can communicate

Shared Memory u Threads in the same program share memory. – Good: can communicate quickly and easily – bad: can stomp each other’s data structures » horrible bugs! u Threads in a program share statics and newed up objects. u Private versions of arguments and locals. COS 461 Fall 1997

Deferring Work with Threads class Deferred. Grade. Report extends Thread { private String student;

Deferring Work with Threads class Deferred. Grade. Report extends Thread { private String student; public Deferred. Grade. Report(String who) { student = who; start(); } public void run() { int grade = calculate. Grade(student); send. Grade. To. Student(student, grade); } COS 461 Fall 1997

Why are Threads Tricky? u Single thread: things change only because the program changes

Why are Threads Tricky? u Single thread: things change only because the program changes them u multi-threaded: things can change “on their own” x = y; x = 17; if(x != y){ // die horribly } COS 461 Fall 1997

Another Thread-Related Disaster class C { private int x = 3; public void increment()

Another Thread-Related Disaster class C { private int x = 3; public void increment() { int r = x; ++r; x = r; } } thread A thread B r = x; 3 ++r; 4 x = r; 4 COS 461 Fall 1997

Mutual Exclusion u protect data from “outside meddling” u use Java’s synchronized keyword class

Mutual Exclusion u protect data from “outside meddling” u use Java’s synchronized keyword class C { private int x = 3; public synchronized void increment() { int r = x; ++r; x = r; } } COS 461 Fall 1997

Synchronized: Details u synchronized method holds a “lock” on the object that the method

Synchronized: Details u synchronized method holds a “lock” on the object that the method is invoked on u if lock is unavailable, you’re put to sleep until you can get it u lock doesn’t prevent access to data, it only prevents locking call return S L E E P call return COS 461 Fall 1997

Synchronized: Details u same thread can acquire the same lock multiple times – recursive

Synchronized: Details u same thread can acquire the same lock multiple times – recursive synchronized methods “work” u also, synchronized statement in Java C c = new C(); … synchronized(c){ ++(c. x); } COS 461 Fall 1997

Deadlock class LLitem { private LLitem next, prev; synchronized void remove(){ synchronized(next){ next->prev =

Deadlock class LLitem { private LLitem next, prev; synchronized void remove(){ synchronized(next){ next->prev = prev; } synchronized(prev){ prev->next = next; } } } u. A waiting for B; B waiting for A u we’re stuck, forever COS 461 Fall 1997

Avoiding Deadlock u key idea: avoid cycles of waiting u can do use special-case

Avoiding Deadlock u key idea: avoid cycles of waiting u can do use special-case design, then convince yourself it’s correct u usually, follow two simple rules – never lock two objects of the same class at the same time – if class C was written before class D, code in C never locks a D object (not even indirectly) COS 461 Fall 1997

Example: Blocking Queue (1. 0) public class Blocking. Queue extends Queue { public synchronized

Example: Blocking Queue (1. 0) public class Blocking. Queue extends Queue { public synchronized void put(Object o) { super. put(o); } public synchronized Object get() { if(super. empty()) return null; else return super. get(); } } COS 461 Fall 1997

Using Blocking. Queue 1. 0 // get from Blocking. Queue bq Object o; do{

Using Blocking. Queue 1. 0 // get from Blocking. Queue bq Object o; do{ o = bq. get(); }while(o == null); Problem: waste CPU time calling get() over and over Solution: when queue is empty, get() should block the calling thread COS 461 Fall 1997

Blocking. Queue 2. 0 public class Blocking. Queue extends Queue { public synchronized void

Blocking. Queue 2. 0 public class Blocking. Queue extends Queue { public synchronized void put(Object o) { super. put(o); } public synchronized Object get() { while(super. empty()) Thread. yield(); return super. get(); } } Deadlock! COS 461 Fall 1997

Blocking. Queue 3. 0 public class Blocking. Queue extends Queue { // put omitted

Blocking. Queue 3. 0 public class Blocking. Queue extends Queue { // put omitted public /*synchronized*/ Object get() { while(super. empty()) Thread. yield(); synchronized(this) { return super. get(); } } } Sometimes returns null COS 461 Fall 1997

Blocking. Queue 4. 0 public class Blocking. Queue extends Queue { public Object get()

Blocking. Queue 4. 0 public class Blocking. Queue extends Queue { public Object get() { Object ret; do{ while(super. empty()) Thread. yield(); synchronized(this) { ret = super. get(); } Works, but inefficient }while(ret == null); return ret; } } COS 461 Fall 1997

Solution: wait/notify u idea: let a thread wait while holding a lock – temporarily

Solution: wait/notify u idea: let a thread wait while holding a lock – temporarily gives up lock while sleeping – awakened when another thread causes something to change u Java syntax – wait(): sleeps temporarily (giving up lock) – notify(): wakes up one sleeper – notify. All() wakes up all sleepers COS 461 Fall 1997

Blocking. Queue: Solution public class Blocking. Queue extends Queue { public synchronized void put(Object

Blocking. Queue: Solution public class Blocking. Queue extends Queue { public synchronized void put(Object o) { super. put(o); notify(); } public synchronized Object get() { while(super. empty()) wait(); return super. get(); } } COS 461 Fall 1997

Wait/Notify Details u several threads can wait simultaneously u wait() releases lock, waits for

Wait/Notify Details u several threads can wait simultaneously u wait() releases lock, waits for wakeup, then reacquires lock before continuing u wake-up not immediate, so condition might not be true when thread returns from wait() – check for condition in while-loop u OK to wake up too many threads; deadly to wake up too few – when in doubt, notify. All() COS 461 Fall 1997