View Javadoc

1   /*
2     File: SynchronizedLong.java
3   
4     Originally written by Doug Lea and released into the public domain.
5     This may be used for any purposes whatsoever without acknowledgment.
6     Thanks for the assistance and support of Sun Microsystems Labs,
7     and everyone contributing, testing, and using this code.
8   
9     History:
10    Date       Who                What
11    19Jun1998  dl               Create public version
12    15Apr2003  dl               Removed redundant "synchronized" for multiply()
13    23jan04    dl               synchronize self-swap case for swap
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 &amp; 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() { // same expression as java.lang.Long
238     long v = get();
239     return (int)(v ^ (v >> 32));
240   }
241 
242   public String toString() { return String.valueOf(get()); }
243 
244 }
245