Chapter 15: Breaking Out of a Blocked IO State

Chapter 17 - The BooleanLock Utility

Java Thread Programming
Paul Hyde
  Copyright 1999 Sams Publishing

BooleanLock Class
The API for BooleanLock consists of the following methods :
public BooleanLock(boolean initialValue)
public BooleanLock()
public synchronized void setValue(boolean newValue)
public synchronized boolean waitToSetTrue(long msTimeout)
        throws InterruptedException
public synchronized boolean waitToSetFalse(long msTimeout)
        throws InterruptedException
public synchronized boolean isTrue()
public synchronized boolean isFalse()
public synchronized boolean waitUntilTrue(long msTimeout)
        throws InterruptedException
public synchronized boolean waitUntilFalse(long msTimeout)
        throws InterruptedException
public synchronized boolean waitUntilStateIs(
        boolean state, long msTimeout) throws InterruptedException
Notice that all the methods are synchronized and that many of them might throw an InterruptedException . The no-argument constructor defaults to use an initial value of false . Every time that setValue() is invoked with a new value, any and all threads blocked waiting in the wait XYZ () methods are notified of the change.
All of the wait XYZ () methods take a timeout value indicating how long they should wait for the condition to be met. A timeout of indicates that the method should wait until the condition is met regardless of how long it takes. Otherwise , the timeout value is the maximum number of milliseconds that should elapse before the method returns. These methods return true if the condition was met, and false if the waiting timed out.
The full code for BooleanLock is shown in Listing 17.1.
Listing 17.1  BooleanLock.javaThe BooleanLock Utility
1: public class BooleanLock extends Object {
2:     private boolean value;
3:
4:     public BooleanLock(boolean initialValue) {
5:         value = initialValue;
6:     }
7:
8:     public BooleanLock() {
9:         this(false);
10:     }
11:
12:     public synchronized void setValue(boolean newValue) {
13:         if (newValue != value) {
14:             value = newValue;
15:             notifyAll();
16:         }
17:     }
18:
19:     public synchronized boolean waitToSetTrue(long msTimeout)
20:             throws InterruptedException {
21:
22:         boolean success = waitUntilFalse(msTimeout);
23:         if (success) {
24:             setValue(true);
25:         }
26:
27:         return success;
28:     }
29:
30:     public synchronized boolean waitToSetFalse(long msTimeout)
31:             throws InterruptedException {
32:
33:         boolean success = waitUntilTrue(msTimeout);
34:         if (success) {
35:             setValue(false);
36:         }
37:
38:         return success;
39:     }
40:
41:     public synchronized boolean isTrue() {
42:         return value;
43:     }
44:
45:     public synchronized boolean isFalse() {
46:         return !value;
47:     }
48:
49:     public synchronized boolean waitUntilTrue(long msTimeout)
50:             throws InterruptedException {
51:
52:         return waitUntilStateIs(true, msTimeout);
53:     }
54:
55:     public synchronized boolean waitUntilFalse(long msTimeout)
56:             throws InterruptedException {
57:
58:         return waitUntilStateIs(false, msTimeout);
59:     }
60:
61:     public synchronized boolean waitUntilStateIs(
62:                 boolean state,
63:                 long msTimeout
64:            ) throws InterruptedException {
65:
66:         if (msTimeout == 0L) {
67:             while (value != state) {
68:                 wait();  // wait indefinitely until notified
69:             }
70:
71:             // condition has finally been met
72:             return true;
73:         }
74:
75:         // only wait for the specified amount of time
76:         long endTime = System.currentTimeMillis() + msTimeout;
77:         long msRemaining = msTimeout;
78:
79:         while ((value != state) && (msRemaining > 0L)) {
80:             wait(msRemaining);
81:             msRemaining = endTime - System.currentTimeMillis();
82:         }
83:
84:         // May have timed out, or may have met value,
85:         // calculate return value.
86:         return (value == state);
87:     }
88: }
The member variable value (line 2) holds the most recent setting. The first constructor (lines 46) sets value to the specified initial state. The second constructor (lines 810) uses a default value of false for the initial state. The setValue() method (lines 1217) is the primary mechanism used to change value . It is synchronized to coordinate access with other threads. If the value passed in truly represents a change (line 13), value is altered (line 14) and any and all waiting threads are notified of the change (line 15). The methods waitToSetTrue() and waitToSetFalse() both might end up calling setValue() .
In waitToSetTrue() (lines 1928), the calling thread waits until it has exclusive access and value is false . If several threads are waiting in this method, only one will get a chance to proceed when value is set to false . Which one of the threads gets to proceed is an arbitrary choice made by the virtual machines thread scheduler. Internally, waitToSetTrue() invokes waitUntilFalse() , passing along the timeout information. The return value of waitUntilFalse() is stored in the local variable success (line 22). If waitUntilFalse() times out, it returns false ; otherwise, it returns true . If true is returned, setValue() is used to alter value (lines 2335). If the call to waitToSetTrue() succeeded in making a change, true is returned. If it times out while waiting, false is returned. If it is interrupted while waiting, an InterruptedException is thrown. The waitToSetFalse() method (lines 3039) works in much the same way as waitToSetTrue() .
The rest of the methods do not affect value , but simply provide information. The isTrue() (lines 4143) and isFalse() (lines 4547) methods provide information about the current setting of value .
The waitUntilTrue() method  (lines 4953) takes a timeout value ( indicating never time out) and blocks until value is true , the specified number of milliseconds elapses, or an InterruptedException is triggered. If a timeout occurs, false is returned; otherwise, true is returned. The waitUntilFalse() method (lines 5559) works in a very similar way. Both methods use the waitUntilStateIs() method as a helper.
The waitUntilStateIs() method  (lines 6187) is passed a value to match and a timeout. It blocks until the value is matched, the timeout occurs, or an InterruptedException is thrown. If it times out waiting for the condition, it returns false ; otherwise, true is returned. A timeout of indicates that it should block until the condition is metregardless of how long that takes. This method uses the full-wait technique shown in Chapter 14 .

Toc


Java Thread Programming
Java Thread Programming
ISBN: 0672315858
EAN: 2147483647
Year: 2005
Pages: 149
Authors: Paul Hyde

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net