KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > util > concurrent > SetOnceFlag


1 /**
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.util.concurrent;
5
6 import com.tc.exception.TCInternalError;
7
8 import java.io.Serializable JavaDoc;
9
10 /**
11  * A class to model a flag that can be set once and only once If you have a boolean in class that should
12  * really only be set once and only once (like a shutdown flag maybe), using this class might help your class stay
13  * implemented correctly <br>
14  * <br>
15  * NOTE: There is purposefully no way to reset the flag. Use of this class is meant to communicate that a particular
16  * flag should be set once and only once (period). <br>
17  * NOTE(2): This class is a lot like a latch in some ways (ie. it can only be set once and not reset). Unlike a latch,
18  * the set() method here is only allowed to be called once (ever). Additionally, there are no wait() style methods on
19  * this flag class
20  *
21  * @author teck
22  */

23 public final class SetOnceFlag implements Serializable JavaDoc {
24   // XXX: review Serialization semantics. Is it possible to get a SetOnceFlag that can be
25
// reset (ie. via serialize/deserialize)
26

27   private final Object JavaDoc lock = new LockObject(); // use a private internal lock for good measure
28

29   private volatile boolean set;
30
31   public SetOnceFlag() {
32     this(false);
33   }
34
35   /**
36    * Create a new SetOnceFlag, optionally <code>set()</code> 'ing the flag immediately
37    *
38    * @param setFlag true if the flag should be created already <code>set()</code>
39    */

40   public SetOnceFlag(final boolean setFlag) {
41     if (setFlag) {
42       this.set = true;
43     }
44   }
45
46   /**
47    * Attempt to set the flag
48    *
49    * @return true if the flag was set, false otherwise
50    * @throws IllegalArgumentException if the value has already been set by a different thread
51    */

52   public void set() {
53     synchronized (lock) {
54       if (set) {
55         throw new IllegalStateException JavaDoc("Flag has already been set");
56       } else {
57         set = true;
58       }
59     }
60   }
61
62   /**
63    * Attempt to atomically set the flag. This differs from <code>set()</set> in that
64    * it doesn't throw an exception if the value has already been set. This method
65    * is useful for flags that might be set more than once, but should act as a guard
66    * against path(s) that should only ever run once.
67    *
68    * NOTE: It is probably almost always wrong to ignore the return value of this method
69    *
70    * @return true iff this invocation actually set the flag, false otherwise
71    */

72   public boolean attemptSet() {
73     try {
74       synchronized (lock) {
75         if (set) { return false; }
76
77         set();
78
79         return set;
80       }
81     } catch (Throwable JavaDoc t) {
82       // this REALLY shouldn't happen, this would be a programming error
83
throw new TCInternalError(t);
84     }
85   }
86
87   /**
88    * Has the flag been already set? README: This is example of how <b>NOT </b> to use this class: <br>
89    *
90    * <pre>
91    * if (!flag.isSet()) {
92    * flag.set();
93    *
94    * // ... do some protected, assumed one-time actions
95    * }
96    * </pre>
97    *
98    * This example code is broken becuase there is no synchronization and/or checking the return value of
99    * <code>set()</code>. It is certainly possible that two threads could execute the body of the <code>if</code>
100    * block A correct implementation might be: <br>
101    *
102    * <pre>
103    * if (flag.attemptSet()) {
104    * // do one time only actions
105    * } else {
106    * // flag was already set
107    * }
108    * </pre>
109    *
110    * @return true if the flag is already set
111    */

112   public boolean isSet() {
113     return set;
114   }
115
116   public String JavaDoc toString() {
117     return "set: " + set;
118   }
119
120   // java.lang.Object isn't Serializable, so use this silly class as a workaround
121
private static class LockObject extends java.lang.Object JavaDoc implements Serializable JavaDoc {
122     // nada
123
}
124
125 }
Popular Tags