Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java...

51
Java ConditionObject: Example Application Douglas C. Schmidt [email protected] www.dre.vanderbilt.edu/~schmidt Institute for Software Integrated Systems Vanderbilt University Nashville, Tennessee, USA

Transcript of Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java...

Page 1: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

Java ConditionObject:

Example Application

Douglas C. [email protected]

www.dre.vanderbilt.edu/~schmidt

Institute for Software

Integrated Systems

Vanderbilt University

Nashville, Tennessee, USA

Page 2: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

2

• Understand what condition variables are

• Note a human known use of condition variables

• Know what pattern they implement

• Recognize common use cases where condition variables are applied

• Recognize the structure & functionality of Java ConditionObject

• Know the key methods defined by theJava ConditionObject class

• Master the use of Condition Objects in practice

Learning Objectives in this Part of the Lesson

usesuses2

ArrayBlocking

Queue

put()take()

Lock

lock()unlock()

uses

take() put()

Consumer Producer

ConditionVariable

await()signal()signalAll()

Page 3: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

3

Applying Java ConditionObject in Practice

Page 4: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

4

• ArrayBlockingQueue is a blocking bounded FIFO queue

Applying Java ConditionObject in Practicepublic class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

See docs.oracle.com/javase/8/docs/api/java/util/concurrent/ArrayBlockingQueue.html

Page 5: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

5

• ArrayBlockingQueue is a blocking bounded FIFO queue

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

Applying Java ConditionObject in Practice

See docs.oracle.com/javase/8/docs/api/java/util/AbstractQueue.html

Page 6: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

6

• ArrayBlockingQueue is a blocking bounded FIFO queue

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

Applying Java ConditionObject in Practice

See docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html

Page 7: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

7

• ArrayBlockingQueue is a blocking bounded FIFO queue

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

Applying Java ConditionObject in Practice

We’ll focus on both the interface & implementation of ArrayBlockingQueue

Page 8: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

8

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

/** The queued items */

final Object[] items;

/** items index for next take,

poll, peek or remove */

int takeIndex;

/** items index for next put,

offer, or add */

int putIndex;

/** Number of elements in

the queue */

int count;

...

Applying Java ConditionObject in Practice

Page 9: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

9

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

/** The queued items */

final Object[] items;

/** items index for next take,

poll, peek or remove */

int takeIndex;

/** items index for next put,

offer, or add */

int putIndex;

/** Number of elements in

the queue */

int count;

...

Applying Java ConditionObject in Practice

Object state that (1) must be protected from race conditions

& (2) is used to coordinate concurrent put() & take() calls

Page 10: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

10

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

/** Main lock guarding access */

final ReentrantLock lock;

/** Condition for waiting takes */

private final Condition notEmpty;

/** Condition for waiting puts */

private final Condition notFull;

...

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

• It has a ReentrantLock& two ConditionObjects

Applying Java ConditionObject in Practice

Used to protect the object state from race conditions

See earlier lesson on “Java ReentrantLock: Example Application”

Page 11: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

11See stackoverflow.com/questions/18490636/condition-give-the-effect-of-having-multiple-wait-sets-per-object

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

/** Main lock guarding access */

final ReentrantLock lock;

/** Condition for waiting takes */

private final Condition notEmpty;

/** Condition for waiting puts */

private final Condition notFull;

...

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

• It has a ReentrantLock& two ConditionObjects

Applying Java ConditionObject in Practice

Two ConditionObjects separate waiting consumers & producers, thus reducing redundant wakeups & checking

Page 12: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

12

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public ArrayBlockingQueue

(int capacity,

boolean fair) {

items =

new Object[capacity];

lock = new ReentrantLock(fair);

notEmpty = lock.newCondition();

notFull = lock.newCondition();

}

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

• It has a ReentrantLock& two ConditionObjects

Applying Java ConditionObject in Practice

Page 13: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

13

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public ArrayBlockingQueue

(int capacity,

boolean fair) {

items =

new Object[capacity];

lock = new ReentrantLock(fair);

notEmpty = lock.newCondition();

notFull = lock.newCondition();

}

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

• It has a ReentrantLock& two ConditionObjects

Applying Java ConditionObject in Practice

The ArrayBlockingQueuehas a fixed-size capacity

Page 14: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

14

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public ArrayBlockingQueue

(int capacity,

boolean fair) {

items =

new Object[capacity];

lock = new ReentrantLock(fair);

notEmpty = lock.newCondition();

notFull = lock.newCondition();

}

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

• It has a ReentrantLock& two ConditionObjects

Applying Java ConditionObject in Practice

The “fair” parameter controls the order in which a group of threads can call methods on the queue

See docs.oracle.com/javase/8/docs/api/java/util/concurrent/ArrayBlockingQueue.html#ArrayBlockingQueue

Page 15: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

15

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public ArrayBlockingQueue

(int capacity,

boolean fair) {

items =

new Object[capacity];

lock = new ReentrantLock(fair);

notEmpty = lock.newCondition();

notFull = lock.newCondition();

}

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

• It has a ReentrantLock& two ConditionObjects

Applying Java ConditionObject in Practice

If true then queue accesses for threads blocked on insertion or removal are processed in FIFO order, whereas if false access order is unspecified

See docs.oracle.com/javase/8/docs/api/java/util/concurrent/ArrayBlockingQueue.html#ArrayBlockingQueue

Page 16: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

16

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public ArrayBlockingQueue

(int capacity,

boolean fair) {

items =

new Object[capacity];

lock = new ReentrantLock(fair);

notEmpty = lock.newCondition();

notFull = lock.newCondition();

}

• ArrayBlockingQueue is a blocking bounded FIFO queue

• It’s implemented using andynamically sized array

• It has a ReentrantLock& two ConditionObjects

Applying Java ConditionObject in Practice

Both ConditionObjects share a common ReentrantLock returned via a factory method

Page 17: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

17

Visualizing the ConditionObject in Action

Page 18: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

18

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

/** Main lock guarding access */

final ReentrantLock lock;

/** Condition for waiting takes */

private final Condition notEmpty;

/** Condition for waiting puts */

private final Condition notFull;

...

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

ArrayBlockingQueue T1

lock

notEmpty notFull

Visualizing Java ConditionObjects in Action

See www.dre.vanderbilt.edu/~schmidt/PDF/monitor.pdf

This pattern synchronizes method execution to ensure only one method runs in an object

at a time & allows an object’s methods to cooperatively schedule their execution

Page 19: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

19

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

/** Main lock guarding access */

final ReentrantLock lock;

/** Condition for waiting takes */

private final Condition notEmpty;

/** Condition for waiting puts */

private final Condition notFull;

...

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Visualizing Java ConditionObjects in Action

Critical Section

ArrayBlockingQueue T1

lock

notEmpty notFull

The steps visualized next apply to both the Monitor Object

pattern & Java condition objects

Page 20: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

20

Visualizing a Java ConditionObject for Take (T1)

Page 21: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

21

notFull notEmpty

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

ArrayBlockingQueue T1

lock

ArrayBlockingQueue<String> q =

new ArrayBlockingQueue<>(10);

...

Visualizing a Java ConditionObject for Take (T1)

Create a bounded blocking queue with a maximum size of 10 elements

Page 22: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

22

notFull notEmpty

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

ArrayBlockingQueue T1

lock

ArrayBlockingQueue<String> q =

new ArrayBlockingQueue<>(10);

...

// Called by thread T1

String s = q.take();

...

Visualizing a Java ConditionObject for Take (T1)

This call to the take() method blocks since the queue is initially empty

Page 23: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

23

notFull notEmpty

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

ArrayBlockingQueue

T1

lock

Visualizing a Java ConditionObject for Take (T1)

When take() is called thread T1 enters the monitor object if there’s no contention of the monitor lock

Page 24: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

24

notFull notEmpty

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

Acquire lock

T1

ArrayBlockingQueue lock

Visualizing a Java ConditionObject for Take (T1)

Thread T1 then acquires the lock & enters the critical section since there’s no contention from other threads

Page 25: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

25

notFull notEmpty

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

Running Thread

T1

ArrayBlockingQueue lock

Visualizing a Java ConditionObject for Take (T1)

The Guarded Suspension pattern waits until the queue’s not empty

See en.wikipedia.org/wiki/Guarded_suspension

Page 26: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

26

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

ArrayBlockingQueue lock

Block on condition

object

Visualizing a Java ConditionObject for Take (T1)

The call to await() atomically blocks T1 & releases the lock

Page 27: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

27

Visualizing a Java Condition Object for Put (T2)

Page 28: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

28

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

Block on condition

object

ArrayBlockingQueue lock

ArrayBlockingQueue<String> q =

new ArrayBlockingQueue<>(10);

...

T2

Visualizing a Java ConditionObject for Put (T2)

This is the same bounded blocking queue with a maximum size of 10 elements

Page 29: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

29

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

Block on condition

object

ArrayBlockingQueue lock

ArrayBlockingQueue<String> q =

new ArrayBlockingQueue<>(10);

...

// Called by thread T2

String s =

new String("...");

...

q.put(s);

...

T2

Visualizing a Java ConditionObject for Put (T2)

Thread T2 puts a new string into the queue, which is currently empty & which has thread T1 waiting on the

notEmpty ConditionObject

Page 30: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

30

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public void put(E e) … {

...

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == items.length)

notFull.await();

insert(e);

} finally {

lock.unlock();

}

}

T2

Visualizing a Java ConditionObject for Put (T2)

When put() is called thread T2

enters the monitor object

Page 31: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

31

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public void put(E e) … {

...

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == items.length)

notFull.await();

insert(e);

} finally {

lock.unlock();

}

}

Acquire lock

T2

Visualizing a Java ConditionObject for Put (T2)

Thread T2 acquires the monitor lock & enters the critical section since there’s no contention from other threads

Page 32: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

32

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public void put(E e) … {

...

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == items.length)

notFull.await();

insert(e);

} finally {

lock.unlock();

}

}

Running Thread

T2

Visualizing a Java ConditionObject for Put (T2)

The Guarded Suspension pattern waits until the queue’s not full

See en.wikipedia.org/wiki/Guarded_suspension

Page 33: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

33

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public void put(E e) … {

...

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == items.length)

notFull.await();

insert(e);

} finally {

lock.unlock();

}

}

Running Thread

T2

Visualizing a Java ConditionObject for Put (T2)

After the condition is satisfied the new element can be inserted into the queue

Page 34: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

34

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

private void insert(E x) {

items[putIndex] = x;

putIndex = inc(putIndex);

++count;

notEmpty.signal();

}

Running Thread

T2

Visualizing a Java ConditionObject for Put (T2)

insert() is not synchronized since it must be called with the lock held

See www.dre.vanderbilt.edu/~schmidt/PDF/locking-patterns.pdf

Page 35: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

35

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

private void insert(E x) {

items[putIndex] = x;

putIndex = inc(putIndex);

++count;

notEmpty.signal();

}

Running Thread

T2

Visualizing a Java ConditionObject for Put (T2)

This method updates the state of the queue

Page 36: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

36

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull notEmpty

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

private void insert(E x) {

items[putIndex] = x;

putIndex = inc(putIndex);

++count;

notEmpty.signal();

}

Running Thread

T2

Visualizing a Java ConditionObject for Put (T2)

It then signals the notEmptycondition object to indicate

the queue’s no longer empty

Page 37: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

37

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public void put(E e) … {

...

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == items.length)

notFull.await();

insert(e);

} finally {

lock.unlock();

}

}Release lock

T2 notEmpty

Visualizing a Java ConditionObject for Put (T2)

The put() method then unlocks the monitor lock

Page 38: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

38

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Critical Section

notFull

T1

ArrayBlockingQueue lock

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public void put(E e) … {

...

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == items.length)

notFull.await();

insert(e);

} finally {

lock.unlock();

}

}

Leave monitor

T2

notEmpty

Visualizing a Java ConditionObject for Put (T2)

The put() method finally leaves the monitor

Page 39: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

39

Visualizing a Condition Object for Take (T1)

Page 40: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

40

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

lock

Unlock on condition

object

T1

notEmpty

Visualizing a Java ConditionObject for Put (T1)

When insert() signals the notEmpty condition thread T1

wakes up & returns in take()

Page 41: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

41

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

notFull

lock

T1

Critical Section

Acquire lock

T1

notEmpty

Visualizing a Java ConditionObject for Put (T1)

Before await() returns the monitor lock will be reacquired atomically

Page 42: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

42

T1

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

lock

T1 Running Thread

notEmpty

Visualizing a Java ConditionObject for Put (T1)

The Guarded Suspension pattern waits to see if the queue is no longer empty

See en.wikipedia.org/wiki/Guarded_suspension

Page 43: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

43

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

lock

T1 Running Thread

notEmpty

Visualizing a Java ConditionObject for Put (T1)

When the condition is satisfied the extract() method is called

Page 44: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

44

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

private E extract() {

final Object[] items =

this.items;

E x =

this.<E>cast

(items[takeIndex]);

items[takeIndex] = null;

takeIndex = inc(takeIndex);

--count;

notFull.signal();

return x;

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

lock

T1 Running Thread

notEmpty

Visualizing a Java ConditionObject for Put (T1)

extract() assumes it’s called with the monitor lock held

Page 45: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

45

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

private E extract() {

final Object[] items =

this.items;

E x =

this.<E>cast

(items[takeIndex]);

items[takeIndex] = null;

takeIndex = inc(takeIndex);

--count;

notFull.signal();

return x;

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

lock

T1 Running Thread

notEmpty

Visualizing a Java ConditionObject for Put (T1)

extract() updates the state of the queue to remove the front item

Page 46: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

46

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

private E extract() {

final Object[] items =

this.items;

E x =

this.<E>cast

(items[takeIndex]);

items[takeIndex] = null;

takeIndex = inc(takeIndex);

--count;

notFull.signal();

return x;

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

lock

T1 Running Thread

notEmpty

Visualizing a Java ConditionObject for Put (T1)

It then signals the notFullCO to alert any thread waiting in put() that the queue’s not full

Page 47: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

47

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

private E extract() {

final Object[] items =

this.items;

E x =

this.<E>cast

(items[takeIndex]);

items[takeIndex] = null;

takeIndex = inc(takeIndex);

--count;

notFull.signal();

return x;

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

lock

T1 Running Thread

notEmpty

Visualizing a Java ConditionObject for Put (T1)

The item that’s extracted is then returned to the caller of take()

Page 48: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

48

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

T1

Releaselock

lock

notEmpty

Visualizing a Java ConditionObject for Put (T1)

The take() method then unlocks the monitor lock

Page 49: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

49

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

Leave monitor

ArrayBlockingQueue

Critical Section

notFull

lock

T1

notEmpty

Visualizing a Java ConditionObject for Put (T1)

The take() method then finally leaves the monitor

Page 50: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

50

public class ArrayBlockingQueue<E>

extends AbstractQueue<E>

implements BlockingQueue<E>,

java.io.Serializable {

...

public E take() ... {

final ReentrantLock lock =

this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await();

return extract();

} finally {

lock.unlock();

}

}

• ReentrantLock & ConditionObjects implement theMonitor Object pattern

ArrayBlockingQueue

Critical Section

notFull

lock

notEmpty

Visualizing a Java ConditionObject for Put (T1)

This example is complex due to the concurrent coordination between threads & the “moving parts” between the lock & condition objects!

Page 51: Java ConditionObject: Example Applicationschmidt/cs891s/2020-PDFs/6.2.6-Java-Con… · of Java ConditionObject •Know the key methods defined by the Java ConditionObject class •Master

51

End of Java ConditionObject: Example Application