001: /*
002: File: SynchronizedChar.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 char 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 SynchronizedChar extends SynchronizedVariable implements
023: Comparable, Cloneable {
024:
025: protected char value_;
026:
027: /**
028: * Make a new SynchronizedChar with the given initial value,
029: * and using its own internal lock.
030: **/
031: public SynchronizedChar(char initialValue) {
032: super ();
033: value_ = initialValue;
034: }
035:
036: /**
037: * Make a new SynchronizedChar with the given initial value,
038: * and using the supplied lock.
039: **/
040: public SynchronizedChar(char initialValue, Object lock) {
041: super (lock);
042: value_ = initialValue;
043: }
044:
045: /**
046: * Return the current value
047: **/
048: public final char get() {
049: synchronized (lock_) {
050: return value_;
051: }
052: }
053:
054: /**
055: * Set to newValue.
056: * @return the old value
057: **/
058:
059: public char set(char newValue) {
060: synchronized (lock_) {
061: char 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(char assumedValue, char 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 SynchronizedChar.
082: * Uses identityHashCode to avoid deadlock when
083: * two SynchronizedChars 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 char swap(SynchronizedChar other) {
091: if (other == this )
092: return get();
093: SynchronizedChar fst = this ;
094: SynchronizedChar 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: * Add amount to value (i.e., set value += amount)
109: * @return the new value
110: **/
111: public char add(char amount) {
112: synchronized (lock_) {
113: return value_ += amount;
114: }
115: }
116:
117: /**
118: * Subtract amount from value (i.e., set value -= amount)
119: * @return the new value
120: **/
121: public char subtract(char amount) {
122: synchronized (lock_) {
123: return value_ -= amount;
124: }
125: }
126:
127: /**
128: * Multiply value by factor (i.e., set value *= factor)
129: * @return the new value
130: **/
131: public synchronized char multiply(char factor) {
132: synchronized (lock_) {
133: return value_ *= factor;
134: }
135: }
136:
137: /**
138: * Divide value by factor (i.e., set value /= factor)
139: * @return the new value
140: **/
141: public char divide(char factor) {
142: synchronized (lock_) {
143: return value_ /= factor;
144: }
145: }
146:
147: public int compareTo(char other) {
148: char val = get();
149: return (val < other) ? -1 : (val == other) ? 0 : 1;
150: }
151:
152: public int compareTo(SynchronizedChar other) {
153: return compareTo(other.get());
154: }
155:
156: public int compareTo(Object other) {
157: return compareTo((SynchronizedChar) other);
158: }
159:
160: public boolean equals(Object other) {
161: if (other != null && other instanceof SynchronizedChar)
162: return get() == ((SynchronizedChar) other).get();
163: else
164: return false;
165: }
166:
167: public int hashCode() { // same hash as Char
168: return (int) (get());
169: }
170:
171: public String toString() {
172: return String.valueOf(get());
173: }
174:
175: }
|