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 org.dbunit.util.concurrent;
015:
016: import org.slf4j.Logger;
017: import org.slf4j.LoggerFactory;
018:
019: /**
020: * A class useful for offloading synch for int instance variables.
021: *
022: * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
023: **/
024:
025: public class SynchronizedInt extends SynchronizedVariable implements
026: Comparable, Cloneable {
027:
028: /**
029: * Logger for this class
030: */
031: private static final Logger logger = LoggerFactory
032: .getLogger(SynchronizedInt.class);
033:
034: protected int value_;
035:
036: /**
037: * Make a new SynchronizedInt with the given initial value,
038: * and using its own internal lock.
039: **/
040: public SynchronizedInt(int initialValue) {
041: super ();
042: value_ = initialValue;
043: }
044:
045: /**
046: * Make a new SynchronizedInt with the given initial value,
047: * and using the supplied lock.
048: **/
049: public SynchronizedInt(int initialValue, Object lock) {
050: super (lock);
051: value_ = initialValue;
052: }
053:
054: /**
055: * Return the current value
056: **/
057: public final int get() {
058: logger.debug("get() - start");
059: synchronized (lock_) {
060: return value_;
061: }
062: }
063:
064: /**
065: * Set to newValue.
066: * @return the old value
067: **/
068:
069: public int set(int newValue) {
070: logger.debug("set(newValue=" + newValue + ") - start");
071:
072: synchronized (lock_) {
073: int old = value_;
074: value_ = newValue;
075: return old;
076: }
077: }
078:
079: /**
080: * Set value to newValue only if it is currently assumedValue.
081: * @return true if successful
082: **/
083: public boolean commit(int assumedValue, int newValue) {
084: logger.debug("commit(assumedValue=" + assumedValue
085: + ", newValue=" + newValue + ") - start");
086:
087: synchronized (lock_) {
088: boolean success = (assumedValue == value_);
089: if (success)
090: value_ = newValue;
091: return success;
092: }
093: }
094:
095: /**
096: * Atomically swap values with another SynchronizedInt.
097: * Uses identityHashCode to avoid deadlock when
098: * two SynchronizedInts attempt to simultaneously swap with each other.
099: * (Note: Ordering via identyHashCode is not strictly guaranteed
100: * by the language specification to return unique, orderable
101: * values, but in practice JVMs rely on them being unique.)
102: * @return the new value
103: **/
104:
105: public int swap(SynchronizedInt other) {
106: logger.debug("swap(other=" + other + ") - start");
107:
108: if (other == this )
109: return get();
110: SynchronizedInt fst = this ;
111: SynchronizedInt snd = other;
112: if (System.identityHashCode(fst) > System.identityHashCode(snd)) {
113: fst = other;
114: snd = this ;
115: }
116: synchronized (fst.lock_) {
117: synchronized (snd.lock_) {
118: fst.set(snd.set(fst.get()));
119: return get();
120: }
121: }
122: }
123:
124: /**
125: * Increment the value.
126: * @return the new value
127: **/
128: public int increment() {
129: logger.debug("increment() - start");
130:
131: synchronized (lock_) {
132: return ++value_;
133: }
134: }
135:
136: /**
137: * Decrement the value.
138: * @return the new value
139: **/
140: public int decrement() {
141: logger.debug("decrement() - start");
142:
143: synchronized (lock_) {
144: return --value_;
145: }
146: }
147:
148: /**
149: * Add amount to value (i.e., set value += amount)
150: * @return the new value
151: **/
152: public int add(int amount) {
153: logger.debug("add(amount=" + amount + ") - start");
154:
155: synchronized (lock_) {
156: return value_ += amount;
157: }
158: }
159:
160: /**
161: * Subtract amount from value (i.e., set value -= amount)
162: * @return the new value
163: **/
164: public int subtract(int amount) {
165: logger.debug("subtract(amount=" + amount + ") - start");
166:
167: synchronized (lock_) {
168: return value_ -= amount;
169: }
170: }
171:
172: /**
173: * Multiply value by factor (i.e., set value *= factor)
174: * @return the new value
175: **/
176: public synchronized int multiply(int factor) {
177: logger.debug("multiply(factor=" + factor + ") - start");
178:
179: synchronized (lock_) {
180: return value_ *= factor;
181: }
182: }
183:
184: /**
185: * Divide value by factor (i.e., set value /= factor)
186: * @return the new value
187: **/
188: public int divide(int factor) {
189: logger.debug("divide(factor=" + factor + ") - start");
190:
191: synchronized (lock_) {
192: return value_ /= factor;
193: }
194: }
195:
196: /**
197: * Set the value to the negative of its old value
198: * @return the new value
199: **/
200: public int negate() {
201: logger.debug("negate() - start");
202:
203: synchronized (lock_) {
204: value_ = -value_;
205: return value_;
206: }
207: }
208:
209: /**
210: * Set the value to its complement
211: * @return the new value
212: **/
213: public int complement() {
214: logger.debug("complement() - start");
215:
216: synchronized (lock_) {
217: value_ = ~value_;
218: return value_;
219: }
220: }
221:
222: /**
223: * Set value to value & b.
224: * @return the new value
225: **/
226: public int and(int b) {
227: logger.debug("and(b=" + b + ") - start");
228:
229: synchronized (lock_) {
230: value_ = value_ & b;
231: return value_;
232: }
233: }
234:
235: /**
236: * Set value to value | b.
237: * @return the new value
238: **/
239: public int or(int b) {
240: logger.debug("or(b=" + b + ") - start");
241:
242: synchronized (lock_) {
243: value_ = value_ | b;
244: return value_;
245: }
246: }
247:
248: /**
249: * Set value to value ^ b.
250: * @return the new value
251: **/
252: public int xor(int b) {
253: logger.debug("xor(b=" + b + ") - start");
254:
255: synchronized (lock_) {
256: value_ = value_ ^ b;
257: return value_;
258: }
259: }
260:
261: public int compareTo(int other) {
262: logger.debug("compareTo(other=" + other + ") - start");
263:
264: int val = get();
265: return (val < other) ? -1 : (val == other) ? 0 : 1;
266: }
267:
268: public int compareTo(SynchronizedInt other) {
269: logger.debug("compareTo(other=" + other + ") - start");
270:
271: return compareTo(other.get());
272: }
273:
274: public int compareTo(Object other) {
275: logger.debug("compareTo(other=" + other + ") - start");
276:
277: return compareTo((SynchronizedInt) other);
278: }
279:
280: public boolean equals(Object other) {
281: logger.debug("equals(other=" + other + ") - start");
282:
283: if (other != null && other instanceof SynchronizedInt)
284: return get() == ((SynchronizedInt) other).get();
285: else
286: return false;
287: }
288:
289: public int hashCode() {
290: logger.debug("hashCode() - start");
291: return get();
292: }
293:
294: public String toString() {
295: logger.debug("toString() - start");
296: return String.valueOf(get());
297: }
298:
299: }
|