week 7 - purdue universitycs180/fall2009web/lecture...producer-consumer a very common scenario a...

46
Week 7 Concurrent Programming: Thread Synchronization CS 180 Sunil Prabhakar Department of Computer Science Purdue University Tuesday, December 8, 2009

Upload: others

Post on 08-Sep-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Week 7

Concurrent Programming: Thread Synchronization

CS 180Sunil PrabhakarDepartment of Computer Science Purdue University

Tuesday, December 8, 2009

Page 2: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Announcements

Exam 1 tonight 6:30 pm - 7:30 pm MTHW 210

2

Tuesday, December 8, 2009

Page 3: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Outcomes

Understand race conditions Critical sections and mutual exclusion Synchronization mechanism

synchronized methods, block of code wait() and notify()

Understand potential problems busy waiting deadlock livelock

3

Tuesday, December 8, 2009

Page 4: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Thread Scheduling

Remember Once a thread is runnable it can be scheduled

at any time It is hard to predict the actual ordering With multiple threads, we must ensure that any

possible interleaving of threads would still be a correct execution

4

Tuesday, December 8, 2009

Page 5: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Race Conditions

If 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 times the task is divided among multiple threads

5

Tuesday, December 8, 2009

Page 6: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Race Example

6

public 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, 2009

Page 7: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Race

Without multiple threads, always correct. With multiple threads, often incorrect! Why?

multiple threads modifying the same value counter++ is not atomic

Atomic operations A java statement translates to multiple

machine level statements the thread can be swapped in the middle of

these machine level statements7

Tuesday, December 8, 2009

Page 8: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

CPU

The memory hierarchy

8

ALU

Cache

Cache (MB)

Registers

Main Memory (GB)

Speed

SizeCost

Tuesday, December 8, 2009

Page 9: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Multi Core possibility

9

Cache (MB)

CoreALU

Cache

Registers

Main Memory (GB)

CoreALU

Cache

Registers

CPU

Tuesday, December 8, 2009

Page 10: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

CPU

Multi Core possibility 2

10

Cache (MB)

Main Memory (GB)

CoreALU

Registers

CoreALU

Registers

Tuesday, December 8, 2009

Page 11: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

CPU

Multi CPU possibility

11

CPU

ALU

Cache

Registers

Main Memory (GB)

ALU

Cache

Registers

Cache (MB) Cache (MB)

ALU

Cache

Registers

Program Data

Tuesday, December 8, 2009

Page 12: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Atomic operations and Caching

Data is operated on in ALUs register = 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 caches this can cause different threads to not see all changes

made by other threads!12

Tuesday, December 8, 2009

Page 13: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Shared mutable state How do we ensure correct behavior? Many problems of synchronization can be

traced to data that is concurrently read and written by multiple threads shared mutable state if no thread writes -- no problems

For 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.

13

Tuesday, December 8, 2009

Page 14: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Critical Section

A section of code that should not be accessed by multiple threads concurrently

We need to guarantee mutual exclusion in these sections

Java solution: use a lock that only one thread holds at a time also called a monitor any object can be locked

14

Tuesday, December 8, 2009

Page 15: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Synchronized

The synchronized keyword can be used to declare a method or block of code as a critical section i.e., only one thread can be executing any

statements in that method or block of code.

15

public synchronized int methodA(){

. . .//Critical section

} public int methodA(){

. . .

synchronized (someObject) {

. . . //Critical section

}

}

Tuesday, December 8, 2009

Page 16: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Method vs. block of code

When synchronized is used with a block of code, we explicitly specify what object should be

used for locking; can arbitrarily limit the critical section can have independent locks for different code.

A synchronized method implicitly locks the object (this) on which the method is called the class, in the case of static methods

16

Tuesday, December 8, 2009

Page 17: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

(No) Race Condition

17

public 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, 2009

Page 18: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Synchronization

Any code that is synchronized can only be executed by a thread that holds the appropriate lock

Only one thread can hold the lock for a given object

Any changes made in a critical section will be visible to all threads once they get the lock (ensured by Java)

18

Tuesday, December 8, 2009

Page 19: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Announcements

No class on Monday No labs next week

19

Tuesday, December 8, 2009

Page 20: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Producer-Consumer

A very common scenario a producer process creates data a consumer process processes data (and

deletes it) e.g., networking, unix pipes, device drivers

A shared data structure (buffer) is used to hold data before processing limited size if empty -- consumer waits if full -- produce waits

20

Tuesday, December 8, 2009

Page 21: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

21

import 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-Consumer

Tuesday, December 8, 2009

Page 22: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

22

public void run(){

String s;

for(int i=0;i<1000;i++){

try{

if(isConsumer){

s = (String)

buffer.removeItem();

System.out.println(“Consumed:” + s);

} else {

s = “Item” + i;

buffer.addItem(s);

System.out.println(“\t\tProduced:” + s);

}

sleep(Math.ceil(Math.random()*10)) ;

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

Tuesday, December 8, 2009

Page 23: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Buffer class

How should the Buffer class be implemented? The buffer is shared mutable state! We must ensure that producers and consumers do

not adversely affect each other. When the producer thread is adding a new entry,

the consumer should not remove an entry and vice versa.

Assume: entries are all packed in the array (i.e., there are

no holes) addition/deletion is done at end of array.

23

Tuesday, December 8, 2009

Page 24: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Potential Solution

24

public class Buffer {

public final static int SIZE = 10;

private Object [] objects = new Object [ SIZE ];

private int count = 0;

public synchronized void addItem ( Object object ) {

objects [ count ++] = object ;

}

public synchronized Object removeItem () {

Object object = objects [--count];

return object ;

}

} Note: typo in book! not count--

Tuesday, December 8, 2009

Page 25: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Problem

If we simply use synchronized methods, what should we do if buffer is full when adding, or buffer is empty when deleting?

We could throw an exception and let the user handle this situation.

Not a good solution. Ideally, we should wait for the other

process to delete (or add) something HOW?

25

Tuesday, December 8, 2009

Page 26: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Potential Solution 2

26

public class Buffer {

. . .

public void addItem ( Object object ) {

while (true) {

synchronized (this) {

if ( count != SIZE ){

objects [ count ++] = object ;

break;

}

}

}

}

public Object removeItem () {

Object object;

while (true) {

synchronized(this) {

if(count != 0 ) {

object = objects [--count];

break;

}

}

}

return object ;

}

}

Tuesday, December 8, 2009

Page 27: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Busy-waiting! This works, but it is inefficient The thread continuously consumes

resources while waiting for something to happen - called busy waiting

We would like the thread to wait until some condition is true.

How do we suspend a thread until some condition is potentially true?

This is achieved using the wait() and notify() methods.

27

Tuesday, December 8, 2009

Page 28: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Thread States

Runnable NotRunnable

start()

sleep()

wait()

notify()wake up

yield()(un)schedule

run() terminatesuncaught exception

terminated

Running

schedule

new thread

Tuesday, December 8, 2009

Page 29: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

wait(), notify(), and notifyAll()

These methods can be called on any object. The calling thread must own the lock

(monitor) for the object When the current thread executes wait(), it

becomes not runnable until the thread is woken up due to a call to notify() or

notifyAll() on the object on which it is waiting the thread is interrupted by some other thread the timeout interval has passed

29

Tuesday, December 8, 2009

Page 30: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

The wait() method

The calling thread gives up its lock on the object until it is woken up or interrupted wait() waits forever to be woken up by notify() or notifyAll

() wait(long timeout)

waits only for timeout milliseconds wait(long timeout, int nanos)

specify interval with greater accuracy

When the thread waits, it gives up the lock on the object (but not other locks)

The thread only resumes after it has re-acquired the lock on the object on which is called wait.

30

Tuesday, December 8, 2009

Page 31: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Notify methods Calling thread must own the lock on the object notifyAll() causes all threads waiting on this

object to be woken up notify() causes one (arbitrarily chosen) thread

waiting on this object to be woken up Both calls result in the lock on the object to be

released one of the newly woken threads will get the lock

and be able to move on Repeated waits are necessary to ensure that

the necessary conditions have been met31

Tuesday, December 8, 2009

Page 32: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Producer-Consumer Solution

32

public class Buffer {

public final static int SIZE = 10;

private Object [] objects = new Object [ SIZE ];

private int count = 0;

public synchronized void addItem ( Object object ) throws InterruptedException {

while ( count == SIZE )

wait ();

objects [ count ++] = object ;

notifyAll ();

}

public synchronized Object removeItem () throws InterruptedException {

while ( count == 0 )

wait ();

Object object = objects [--count];

notifyAll ();

return object ;

}

}

Tuesday, December 8, 2009

Page 33: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Synchronization Examples

33

Tuesday, December 8, 2009

Page 34: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Bank Account Example

Create a multi-threaded banking class. Allow threads to

deposit; withdraw; getBalance Only one thread should be modifying

balance at any time. Multiple threads can be reading balance at

the same time.

34

Tuesday, December 8, 2009

Page 35: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Solution

Keep a count of current active readers All access to readers is synchronized on

the account object. Changes to balance are made only in the

changeBalance() method which is synchronized on the account object. can only change if there are no current readers note: wait() until this is true note: readers must notify() when done!

35

Tuesday, December 8, 2009

Page 36: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

SynchronizedAccount

36

public class SynchronizedAccount {

private double balance = 0.0;

private int readers = 0;

public double getBalance () throws InterruptedException {

double amount ;

synchronized ( this ) {

readers ++;

}

amount = balance ;

synchronized ( this ) {

if( --readers == 0 )

notifyAll ();

}

return amount ;

}

public void deposit ( double amount ) throws InterruptedException {

changeBalance ( amount );

System .out. println (" Deposited $" + amount + "." );

}

. . .

}

Tuesday, December 8, 2009

Page 37: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

SynchronizedAccount

37

public boolean withdraw ( double amount ) throws InterruptedException {

boolean success = changeBalance ( -amount );

if( success )

System.out.println (" Withdrew $" + amount + "." ) ;

else

System.out.println (" Failed to withdraw $" + amount + ": insufficient funds ." );

return success ;

}

private synchronized boolean changeBalance ( double amount ) throws InterruptedException {

boolean success ;

while ( readers > 0 )

wait ();

if( success = ( balance + amount > 0) )

balance += amount ;

return success ;

}

}

Tuesday, December 8, 2009

Page 38: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Account tester

38

public class TestSynchronizedAccount extends Thread {

static final int THREADS = 10;

static SynchronizedAccount account = new SynchronizedAccount();

static TestSynchronizedAccount[] threads = new TestSynchronizedAccount[THREADS];

static double netChange[] = new double[THREADS];

int threadID;

public TestSynchronizedAccount(int id) { threadID=id; }

public static void main(String[] args) {

double totalChange=0;

try{

for(int i=0;i<THREADS;i++) {

threads[i] = new TestSynchronizedAccount(i);

threads[i].start();

}

for(int i=0;i<THREADS;i++){

threads[i].join();

totalChange+=netChange[i];

}

System.out.println("Net Change: " + totalChange + "\tCurrent Balance: "+ account.getBalance());

} catch (InterruptedException e) { e.printStackTrace(); }

}

Tuesday, December 8, 2009

Page 39: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Account tester (cont.)

39

public void run(){

double totalWithdrawals=0;

double amount;

try{

for(int i=0;i<10;i++) {

amount = (Math.ceil(Math.random()*10000))/100.0;

if(Math.random() <0.5) {

if(TestSynchronizedAccount.account.withdraw(amount)) {

netChange[i]-=amount;

System.out.println("\t\t\tThread " + i + " Withdrew: " + amount);

}

} else {

TestSynchronizedAccount.account.deposit(amount);

netChange[i]+=amount;

System.out.println("\t\t\tThread " + i + " Deposited: " + amount);

}

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

Tuesday, December 8, 2009

Page 40: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Starvation, Livelock, Deadlock

It is possible for the changeBalance() method to always be prevented from running by some checkBalance() method

Thus deposit/withdrawal can starve A deadlock is a situation where more than one

threads are waiting for each other in a circular fashion -- none of them will ever make progress!

Another potential problem is livelock, i.e., some thread(s) is making progress, but some others may be blocked indefinitely

40

Tuesday, December 8, 2009

Page 41: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

The Dining Philosophers

Consider N philosophers that think and eat There is a circular table with N seats and N

chopsticks When a philosopher wants to eat she tries

to pick up two chopsticks and then eats Once done eating she replaces (after

washing of course) the chopsticks. How do we simulate this? There should be no starving philosopher!

41

Tuesday, December 8, 2009

Page 42: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Dining Philosopher (deadlock)

42

public void DeadlockPhilosopher extends Thread {

public static final int SEATS = 5;

private static boolean [] chopsticks = new boolean [SEATS];

private int seat ;

public DeadlockPhilosopher ( int seat ) {

this.seat = seat ;

}

public void run () {

try {

getChopstick ( seat );

Thread.sleep (50) ;

getChopstick ( seat - 1 );

} catch ( InterruptedException e ) {

e. printStackTrace ();

}

eat ();

}

Tuesday, December 8, 2009

Page 43: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Dining Philosophers (cont.)

43

private void getChopstick ( int location ) throws InterruptedException {

if( location < 0 )

location += SEATS ;

synchronized ( chopsticks ) {

while ( chopsticks [ location ] )

chopsticks.wait ();

chopsticks [ location ] = true ;

}

System . out. println (" Philosopher " + seat + " picked up chopstick " + location + ".");

}

private void eat () { // done eating , put back chopsticks

synchronized ( chopsticks ) {

chopsticks [ seat ] = false ;

if( seat == 0)

chopsticks [ SEATS - 1] = false ;

else

chopsticks [ seat - 1] = false ;

chopsticks.notifyAll ();

}

}

}

Tuesday, December 8, 2009

Page 44: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

Dining Philosophers (Good)

44

import java.util.*;

public class DiningPhilosopher2 extends Thread {

public static final int SEATS = 5;

private static boolean [] chopsticks = new boolean [ SEATS ];

private int seat ;

public DiningPhilosopher2 ( int seat ) { this.seat = seat; }

public static void main ( String args []) {

for ( int i = 0; i < SEATS ; i++ )

chopsticks [i] = false ;

DiningPhilosopher2 [] philosophers = new DiningPhilosopher2 [ SEATS ];

for ( int i = 0; i < SEATS ; i++ ) {

philosophers [i] = new DiningPhilosopher2 ( i );

philosophers[i].start ();

}

try {

for ( int i = 0; i < SEATS ; i++ )

philosophers[i].join ();

} catch ( InterruptedException e ) { e.printStackTrace (); }

System.out.println ("All philosophers done.");

}

Tuesday, December 8, 2009

Page 45: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

45

public void run () {

for ( int i = 0; i < 100; i++ ) {

think ();

getChopsticks ();

eat ();

}

}

private void think () {

Random random = new Random ();

try {

sleep ( random . nextInt (20) + 10 );

} catch ( InterruptedException e ) { e. printStackTrace (); }

}

private void eat () {

// eat rice first

synchronized ( chopsticks ) {

chopsticks [ seat ] = false ;

if( seat == 0)

chopsticks [ SEATS - 1] = false ;

else

chopsticks [ seat - 1] = false ;

chopsticks . notifyAll ();

}

}

Tuesday, December 8, 2009

Page 46: Week 7 - Purdue Universitycs180/Fall2009Web/lecture...Producer-Consumer A very common scenario a producer process creates data a consumer process processes data (and deletes it) e.g.,

46

private void getChopsticks () {

int location1 = seat ;

int location2 ;

if( seat == 0 )

location2 = SEATS - 1;

else

location2 = seat - 1;

synchronized ( chopsticks ) {

while ( chopsticks [ location1 ] || chopsticks [ location2 ] ) {

try {

chopsticks . wait ();

} catch ( InterruptedException e ) { e. printStackTrace (); }

}

chopsticks [ location1 ] = true ;

chopsticks [ location2 ] = true ;

}

System.out.println (" Philosopher " + seat + " picked up chopsticks " + location1 + " and " + location2 + ".");

}

}

Tuesday, December 8, 2009