01: /*
02: File: LayeredSync.java
03:
04: Originally written by Doug Lea and released into the public domain.
05: This may be used for any purposes whatsoever without acknowledgment.
06: Thanks for the assistance and support of Sun Microsystems Labs,
07: and everyone contributing, testing, and using this code.
08:
09: History:
10: Date Who What
11: 1Aug1998 dl Create public version
12: */
13:
14: package EDU.oswego.cs.dl.util.concurrent;
15:
16: /**
17: * A class that can be used to compose Syncs.
18: * A LayeredSync object manages two other Sync objects,
19: * <em>outer</em> and <em>inner</em>. The acquire operation
20: * invokes <em>outer</em>.acquire() followed by <em>inner</em>.acquire(),
21: * but backing out of outer (via release) upon an exception in inner.
22: * The other methods work similarly.
23: * <p>
24: * LayeredSyncs can be used to compose arbitrary chains
25: * by arranging that either of the managed Syncs be another
26: * LayeredSync.
27: *
28: * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
29: **/
30:
31: public class LayeredSync implements Sync {
32:
33: protected final Sync outer_;
34: protected final Sync inner_;
35:
36: /**
37: * Create a LayeredSync managing the given outer and inner Sync
38: * objects
39: **/
40:
41: public LayeredSync(Sync outer, Sync inner) {
42: outer_ = outer;
43: inner_ = inner;
44: }
45:
46: public void acquire() throws InterruptedException {
47: outer_.acquire();
48: try {
49: inner_.acquire();
50: } catch (InterruptedException ex) {
51: outer_.release();
52: throw ex;
53: }
54: }
55:
56: public boolean attempt(long msecs) throws InterruptedException {
57:
58: long start = (msecs <= 0) ? 0 : System.currentTimeMillis();
59: long waitTime = msecs;
60:
61: if (outer_.attempt(waitTime)) {
62: try {
63: if (msecs > 0)
64: waitTime = msecs
65: - (System.currentTimeMillis() - start);
66: if (inner_.attempt(waitTime))
67: return true;
68: else {
69: outer_.release();
70: return false;
71: }
72: } catch (InterruptedException ex) {
73: outer_.release();
74: throw ex;
75: }
76: } else
77: return false;
78: }
79:
80: public void release() {
81: inner_.release();
82: outer_.release();
83: }
84:
85: }
|