Presentation is loading. Please wait.

Presentation is loading. Please wait.

308-203A Introduction to Computing II Lecture 18: Concurrency Issues Fall Session 2000.

Similar presentations


Presentation on theme: "308-203A Introduction to Computing II Lecture 18: Concurrency Issues Fall Session 2000."— Presentation transcript:

1 308-203A Introduction to Computing II Lecture 18: Concurrency Issues Fall Session 2000

2 From last time We’ve seen how it is often natural to write programs with multiple “threads” running at the same time. This introduced some issues: Race conditions: threads may execute at different speeds Data hazards: threads which share data must “synchronize” accesses to that data to avoid potential data corruption These things happen in an indeterminite, spontaneous and unpredictable way, governed only by Murphy’s Law

3 Taking Control of Threads We can make this process less haphazard by letting threads control their execution. One way to do this in Java is with the sleep( ) method, which causes the calling thread to stop running for a fixed period of time in msec: e.g. sleep(5000) ; // wake up in 5 seconds

4 Taking Control of Threads A smoother way to allow other threads to run without specifying a specific time to wait is yield( ). Example two threads running the following code: run( ) { for (int j=0; j < 5; j++) { System.out.println(j); yield( ); }

5 Taking Control of Threads A smoother way to allow other threads to run without specifying a specific time to wait is yield( ). Example two threads running the following code: run( ) { for (int j=0; j < 5; j++) { System.out.println(j); yield( ); } Most likely output: 1 2 3

6 Taking Control of Threads Another way to control thread execution is with priorities: public final static int MIN_PRIORITY = 1; public final static int NORM_PRIORITY = 5; public final static int MAX_PRIORITY = 10; The paradigmatic example is a flight-control system with two tasks: Don’t-Crash-Into-The-Mountain task (high priority) Copilot’s-Tetris-Game task (low priority)

7 Priorities Introduce Issues Q. Should high priority tasks always run over lower priority tasks, or should it be merely preferential?

8 Priorities Introduce Issues Q. Should high priority tasks always run over lower priority tasks, or should it be merely preferential? A. In Java, priority is strict, and a higher-priority thread cannot even give precedence to lower-priority threads by yield-ing The consequences of a priority policy can sometimes be devastating…

9 Starvation Let’s say the “Don’t-Crash-Into-The-Mountain” task never sleeps… The “Copilot’s-Tetris-Game” task will never run. Result: It is very important for higher priority tasks to intentionally sleep or otherwise release the processor periodically.

10 From last time Data hazards were resolved by “mutually exclusive” access to methods labelled as synchronized: Sychronized code is effectively executed as a unit, such that other threads cannot simultaneously enter potentially dangerous “critical sections” simultaneously This also may be dangerous…

11 The Dining Philosophers A group of philosophers are seated around a table, each with a bowl or rice. Between every two philosophers is one chopstick. Most of the time the philosophers contemplate, but periodically they grow hungry and decide to eat. To eat, a philospher must have both neighboring chopsticks. Only one chopstick may be picked up at a time. Once a philosopher picks up a chopstick, she keeps it until finished eating

12 The Dining Philosophers

13 The Problem Suppose each philosopher simultaneously grabs the chopstick to her left… Now everyone has ONE chopstick but no one can eat!

14 The Dining Philosophers

15 Possible solutions: Leave one chair empty Pick up both chopsticks simultaneously Have some philosophers always pick up the left chopstick first while others always pick up the right one first

16 Deadlock This phenomenon is generically refered to as Deadlock It can occur when concurrent threads compete to acquire exclusive resources of various kinds. In general, deadlocks correspond to cycles in wait-graphs, e.g. “A” waits for “B” waits for “C” waits for “A” A B C wait-for

17 From Dining Philosohers to “Synchronized” Methods Unfortunately, “synchronized” methods can do exactly that: class Foo { synchronized int f( Foo otherFoo ) { return otherFoo.g( ); } synchronized int g( ) { return 0; } }

18 From Dining Philosohers to “Synchronized” Methods Unfortunately, “synchronized” methods can do exactly that: Let there be: Foo x = new Foo( ) ; Foo y = new Foo( ) ; And two threads which simultaneously do the following: THREAD A: x.f(y) THREAD B:y.f(x)

19 From Dining Philosohers to “Synchronized” Methods Unfortunately, “synchronized” methods can do exactly that: 1. THREAD A: x.f(y) => Thread A locks x 2. THREAD B:y.f(x) => Thread B locks y 3. THREAD A: We can’t call y.g( ) without the lock for y 4. THREAD B: We can’t call x.g( ) without the lock for x

20 The Worst of Both Worlds Combining priorities with mutual-exclusion can lead to hard-to-debug phenomena, like the case of the priority inversion bug in the Mars Pathfinder, 1997. For details, check out http://www.time-rover.com/Priority.html

21 Any questions?


Download ppt "308-203A Introduction to Computing II Lecture 18: Concurrency Issues Fall Session 2000."

Similar presentations


Ads by Google