001: /*
002: File: SynchronizedInt.java
003:
004: Originally written by Doug Lea and released into the public domain.
005: This may be used for any purposes whatsoever without acknowledgment.
006: Thanks for the assistance and support of Sun Microsystems Labs,
007: and everyone contributing, testing, and using this code.
008:
009: History:
010: Date Who What
011: 19Jun1998 dl Create public version
012: */
013:
014: package EDU.oswego.cs.dl.util.concurrent;
015:
016: /**
017: * A class useful for offloading synch for int instance variables.
018: *
019: * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
020: **/
021:
022: public class SynchronizedInt extends SynchronizedVariable implements
023: Comparable, Cloneable {
024:
025: protected int value_;
026:
027: /**
028: * Make a new SynchronizedInt with the given initial value,
029: * and using its own internal lock.
030: **/
031: public SynchronizedInt(int initialValue) {
032: super ();
033: value_ = initialValue;
034: }
035:
036: /**
037: * Make a new SynchronizedInt with the given initial value,
038: * and using the supplied lock.
039: **/
040: public SynchronizedInt(int initialValue, Object lock) {
041: super (lock);
042: value_ = initialValue;
043: }
044:
045: /**
046: * Return the current value
047: **/
048: public final int get() {
049: synchronized (lock_) {
050: return value_;
051: }
052: }
053:
054: /**
055: * Set to newValue.
056: * @return the old value
057: **/
058:
059: public int set(int newValue) {
060: synchronized (lock_) {
061: int old = value_;
062: value_ = newValue;
063: return old;
064: }
065: }
066:
067: /**
068: * Set value to newValue only if it is currently assumedValue.
069: * @return true if successful
070: **/
071: public boolean commit(int assumedValue, int newValue) {
072: synchronized (lock_) {
073: boolean success = (assumedValue == value_);
074: if (success)
075: value_ = newValue;
076: return success;
077: }
078: }
079:
080: /**
081: * Atomically swap values with another SynchronizedInt.
082: * Uses identityHashCode to avoid deadlock when
083: * two SynchronizedInts attempt to simultaneously swap with each other.
084: * (Note: Ordering via identyHashCode is not strictly guaranteed
085: * by the language specification to return unique, orderable
086: * values, but in practice JVMs rely on them being unique.)
087: * @return the new value
088: **/
089:
090: public int swap(SynchronizedInt other) {
091: if (other == this )
092: return get();
093: SynchronizedInt fst = this ;
094: SynchronizedInt snd = other;
095: if (System.identityHashCode(fst) > System.identityHashCode(snd)) {
096: fst = other;
097: snd = this ;
098: }
099: synchronized (fst.lock_) {
100: synchronized (snd.lock_) {
101: fst.set(snd.set(fst.get()));
102: return get();
103: }
104: }
105: }
106:
107: /**
108: * Increment the value.
109: * @return the new value
110: **/
111: public int increment() {
112: synchronized (lock_) {
113: return ++value_;
114: }
115: }
116:
117: /**
118: * Decrement the value.
119: * @return the new value
120: **/
121: public int decrement() {
122: synchronized (lock_) {
123: return --value_;
124: }
125: }
126:
127: /**
128: * Add amount to value (i.e., set value += amount)
129: * @return the new value
130: **/
131: public int add(int amount) {
132: synchronized (lock_) {
133: return value_ += amount;
134: }
135: }
136:
137: /**
138: * Subtract amount from value (i.e., set value -= amount)
139: * @return the new value
140: **/
141: public int subtract(int amount) {
142: synchronized (lock_) {
143: return value_ -= amount;
144: }
145: }
146:
147: /**
148: * Multiply value by factor (i.e., set value *= factor)
149: * @return the new value
150: **/
151: public synchronized int multiply(int factor) {
152: synchronized (lock_) {
153: return value_ *= factor;
154: }
155: }
156:
157: /**
158: * Divide value by factor (i.e., set value /= factor)
159: * @return the new value
160: **/
161: public int divide(int factor) {
162: synchronized (lock_) {
163: return value_ /= factor;
164: }
165: }
166:
167: /**
168: * Set the value to the negative of its old value
169: * @return the new value
170: **/
171: public int negate() {
172: synchronized (lock_) {
173: value_ = -value_;
174: return value_;
175: }
176: }
177:
178: /**
179: * Set the value to its complement
180: * @return the new value
181: **/
182: public int complement() {
183: synchronized (lock_) {
184: value_ = ~value_;
185: return value_;
186: }
187: }
188:
189: /**
190: * Set value to value & b.
191: * @return the new value
192: **/
193: public int and(int b) {
194: synchronized (lock_) {
195: value_ = value_ & b;
196: return value_;
197: }
198: }
199:
200: /**
201: * Set value to value | b.
202: * @return the new value
203: **/
204: public int or(int b) {
205: synchronized (lock_) {
206: value_ = value_ | b;
207: return value_;
208: }
209: }
210:
211: /**
212: * Set value to value ^ b.
213: * @return the new value
214: **/
215: public int xor(int b) {
216: synchronized (lock_) {
217: value_ = value_ ^ b;
218: return value_;
219: }
220: }
221:
222: public int compareTo(int other) {
223: int val = get();
224: return (val < other) ? -1 : (val == other) ? 0 : 1;
225: }
226:
227: public int compareTo(SynchronizedInt other) {
228: return compareTo(other.get());
229: }
230:
231: public int compareTo(Object other) {
232: return compareTo((SynchronizedInt) other);
233: }
234:
235: public boolean equals(Object other) {
236: if (other != null && other instanceof SynchronizedInt)
237: return get() == ((SynchronizedInt) other).get();
238: else
239: return false;
240: }
241:
242: public int hashCode() {
243: return get();
244: }
245:
246: public String toString() {
247: return String.valueOf(get());
248: }
249:
250: }
|