1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jdiagnose.concurrent;
17
18 /***
19 * A class useful for offloading synch for long instance variables.
20 *
21 * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
22 **/
23
24 public class SynchronizedLong extends SynchronizedVariable implements Comparable, Cloneable {
25
26 protected long value_;
27
28 /***
29 * Make a new SynchronizedLong with the given initial value,
30 * and using its own internal lock.
31 **/
32 public SynchronizedLong(long initialValue) {
33 super();
34 value_ = initialValue;
35 }
36
37 /***
38 * Make a new SynchronizedLong with the given initial value,
39 * and using the supplied lock.
40 **/
41 public SynchronizedLong(long initialValue, Object lock) {
42 super(lock);
43 value_ = initialValue;
44 }
45
46 /***
47 * Return the current value
48 **/
49 public final long get() { synchronized(lock_) { return value_; } }
50
51 /***
52 * Set to newValue.
53 * @return the old value
54 **/
55
56 public long set(long newValue) {
57 synchronized (lock_) {
58 long old = value_;
59 value_ = newValue;
60 return old;
61 }
62 }
63
64 /***
65 * Set value to newValue only if it is currently assumedValue.
66 * @return true if successful
67 **/
68 public boolean commit(long assumedValue, long newValue) {
69 synchronized(lock_) {
70 boolean success = (assumedValue == value_);
71 if (success) value_ = newValue;
72 return success;
73 }
74 }
75
76 /***
77 * Atomically swap values with another SynchronizedLong.
78 * Uses identityHashCode to avoid deadlock when
79 * two SynchronizedLongs attempt to simultaneously swap with each other.
80 * @return the new value
81 **/
82
83 public long swap(SynchronizedLong other) {
84 if (other == this) return get();
85 SynchronizedLong fst = this;
86 SynchronizedLong snd = other;
87 if (System.identityHashCode(fst) > System.identityHashCode(snd)) {
88 fst = other;
89 snd = this;
90 }
91 synchronized(fst.lock_) {
92 synchronized(snd.lock_) {
93 fst.set(snd.set(fst.get()));
94 return get();
95 }
96 }
97 }
98
99 /***
100 * Increment the value.
101 * @return the new value
102 **/
103 public long increment() {
104 synchronized (lock_) {
105 return ++value_;
106 }
107 }
108
109 /***
110 * Decrement the value.
111 * @return the new value
112 **/
113 public long decrement() {
114 synchronized (lock_) {
115 return --value_;
116 }
117 }
118
119 /***
120 * Add amount to value (i.e., set value += amount)
121 * @return the new value
122 **/
123 public long add(long amount) {
124 synchronized (lock_) {
125 return value_ += amount;
126 }
127 }
128
129 /***
130 * Subtract amount from value (i.e., set value -= amount)
131 * @return the new value
132 **/
133 public long subtract(long amount) {
134 synchronized (lock_) {
135 return value_ -= amount;
136 }
137 }
138
139 /***
140 * Multiply value by factor (i.e., set value *= factor)
141 * @return the new value
142 **/
143 public long multiply(long factor) {
144 synchronized (lock_) {
145 return value_ *= factor;
146 }
147 }
148
149 /***
150 * Divide value by factor (i.e., set value /= factor)
151 * @return the new value
152 **/
153 public long divide(long factor) {
154 synchronized (lock_) {
155 return value_ /= factor;
156 }
157 }
158
159 /***
160 * Set the value to the negative of its old value
161 * @return the new value
162 **/
163 public long negate() {
164 synchronized (lock_) {
165 value_ = -value_;
166 return value_;
167 }
168 }
169
170 /***
171 * Set the value to its complement
172 * @return the new value
173 **/
174 public long complement() {
175 synchronized (lock_) {
176 value_ = ~value_;
177 return value_;
178 }
179 }
180
181 /***
182 * Set value to value & b.
183 * @return the new value
184 **/
185 public long and(long b) {
186 synchronized (lock_) {
187 value_ = value_ & b;
188 return value_;
189 }
190 }
191
192 /***
193 * Set value to value | b.
194 * @return the new value
195 **/
196 public long or(long b) {
197 synchronized (lock_) {
198 value_ = value_ | b;
199 return value_;
200 }
201 }
202
203
204 /***
205 * Set value to value ^ b.
206 * @return the new value
207 **/
208 public long xor(long b) {
209 synchronized (lock_) {
210 value_ = value_ ^ b;
211 return value_;
212 }
213 }
214
215
216 public int compareTo(long other) {
217 long val = get();
218 return (val < other)? -1 : (val == other)? 0 : 1;
219 }
220
221 public int compareTo(SynchronizedLong other) {
222 return compareTo(other.get());
223 }
224
225 public int compareTo(Object other) {
226 return compareTo((SynchronizedLong)other);
227 }
228
229 public boolean equals(Object other) {
230 if (other != null &&
231 other instanceof SynchronizedLong)
232 return get() == ((SynchronizedLong)other).get();
233 else
234 return false;
235 }
236
237 public int hashCode() {
238 long v = get();
239 return (int)(v ^ (v >> 32));
240 }
241
242 public String toString() { return String.valueOf(get()); }
243
244 }
245