001: /*
002: File: SynchronizedLong.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 long 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 SynchronizedLong extends SynchronizedVariable implements
023: Comparable, Cloneable {
024:
025: protected long value_;
026:
027: /**
028: * Make a new SynchronizedLong with the given initial value,
029: * and using its own internal lock.
030: **/
031: public SynchronizedLong(long initialValue) {
032: super ();
033: value_ = initialValue;
034: }
035:
036: /**
037: * Make a new SynchronizedLong with the given initial value,
038: * and using the supplied lock.
039: **/
040: public SynchronizedLong(long initialValue, Object lock) {
041: super (lock);
042: value_ = initialValue;
043: }
044:
045: /**
046: * Return the current value
047: **/
048: public final long get() {
049: synchronized (lock_) {
050: return value_;
051: }
052: }
053:
054: /**
055: * Set to newValue.
056: * @return the old value
057: **/
058:
059: public long set(long newValue) {
060: synchronized (lock_) {
061: long 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(long assumedValue, long 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 SynchronizedLong.
082: * Uses identityHashCode to avoid deadlock when
083: * two SynchronizedLongs attempt to simultaneously swap with each other.
084: * @return the new value
085: **/
086:
087: public long swap(SynchronizedLong other) {
088: if (other != this ) {
089: SynchronizedLong fst = this ;
090: SynchronizedLong snd = other;
091: if (System.identityHashCode(fst) > System
092: .identityHashCode(snd)) {
093: fst = other;
094: snd = this ;
095: }
096: synchronized (fst.lock_) {
097: synchronized (snd.lock_) {
098: fst.set(snd.set(fst.get()));
099: }
100: }
101: }
102: return value_;
103: }
104:
105: /**
106: * Increment the value.
107: * @return the new value
108: **/
109: public long increment() {
110: synchronized (lock_) {
111: return ++value_;
112: }
113: }
114:
115: /**
116: * Decrement the value.
117: * @return the new value
118: **/
119: public long decrement() {
120: synchronized (lock_) {
121: return --value_;
122: }
123: }
124:
125: /**
126: * Add amount to value (i.e., set value += amount)
127: * @return the new value
128: **/
129: public long add(long amount) {
130: synchronized (lock_) {
131: return value_ += amount;
132: }
133: }
134:
135: /**
136: * Subtract amount from value (i.e., set value -= amount)
137: * @return the new value
138: **/
139: public long subtract(long amount) {
140: synchronized (lock_) {
141: return value_ -= amount;
142: }
143: }
144:
145: /**
146: * Multiply value by factor (i.e., set value *= factor)
147: * @return the new value
148: **/
149: public synchronized long multiply(long factor) {
150: synchronized (lock_) {
151: return value_ *= factor;
152: }
153: }
154:
155: /**
156: * Divide value by factor (i.e., set value /= factor)
157: * @return the new value
158: **/
159: public long divide(long factor) {
160: synchronized (lock_) {
161: return value_ /= factor;
162: }
163: }
164:
165: /**
166: * Set the value to the negative of its old value
167: * @return the new value
168: **/
169: public long negate() {
170: synchronized (lock_) {
171: value_ = -value_;
172: return value_;
173: }
174: }
175:
176: /**
177: * Set the value to its complement
178: * @return the new value
179: **/
180: public long complement() {
181: synchronized (lock_) {
182: value_ = ~value_;
183: return value_;
184: }
185: }
186:
187: /**
188: * Set value to value & b.
189: * @return the new value
190: **/
191: public long and(long b) {
192: synchronized (lock_) {
193: value_ = value_ & b;
194: return value_;
195: }
196: }
197:
198: /**
199: * Set value to value | b.
200: * @return the new value
201: **/
202: public long or(long b) {
203: synchronized (lock_) {
204: value_ = value_ | b;
205: return value_;
206: }
207: }
208:
209: /**
210: * Set value to value ^ b.
211: * @return the new value
212: **/
213: public long xor(long b) {
214: synchronized (lock_) {
215: value_ = value_ ^ b;
216: return value_;
217: }
218: }
219:
220: public int compareTo(long other) {
221: long val = get();
222: return (val < other) ? -1 : (val == other) ? 0 : 1;
223: }
224:
225: public int compareTo(SynchronizedLong other) {
226: return compareTo(other.get());
227: }
228:
229: public int compareTo(Object other) {
230: return compareTo((SynchronizedLong) other);
231: }
232:
233: public boolean equals(Object other) {
234: if (other != null && other instanceof SynchronizedLong)
235: return get() == ((SynchronizedLong) other).get();
236: else
237: return false;
238: }
239:
240: public int hashCode() { // same expression as java.lang.Long
241: long v = get();
242: return (int) (v ^ (v >> 32));
243: }
244:
245: public String toString() {
246: return String.valueOf(get());
247: }
248:
249: }
|