View Javadoc
1   //******************************************************************************
2   //
3   // File:    SharedLong.java
4   // Package: edu.rit.pj.reduction
5   // Unit:    Class edu.rit.pj.reduction.SharedLong
6   //
7   // This Java source file is copyright (C) 2007 by Alan Kaminsky. All rights
8   // reserved. For further information, contact the author, Alan Kaminsky, at
9   // ark@cs.rit.edu.
10  //
11  // This Java source file is part of the Parallel Java Library ("PJ"). PJ is free
12  // software; you can redistribute it and/or modify it under the terms of the GNU
13  // General Public License as published by the Free Software Foundation; either
14  // version 3 of the License, or (at your option) any later version.
15  //
16  // PJ is distributed in the hope that it will be useful, but WITHOUT ANY
17  // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18  // A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19  //
20  // Linking this library statically or dynamically with other modules is making a
21  // combined work based on this library. Thus, the terms and conditions of the GNU
22  // General Public License cover the whole combination.
23  //
24  // As a special exception, the copyright holders of this library give you
25  // permission to link this library with independent modules to produce an
26  // executable, regardless of the license terms of these independent modules, and
27  // to copy and distribute the resulting executable under terms of your choice,
28  // provided that you also meet, for each linked independent module, the terms
29  // and conditions of the license of that module. An independent module is a module
30  // which is not derived from or based on this library. If you modify this library,
31  // you may extend this exception to your version of the library, but you are not
32  // obligated to do so. If you do not wish to do so, delete this exception
33  // statement from your version.
34  //
35  // A copy of the GNU General Public License is provided in the file gpl.txt. You
36  // may also obtain a copy of the GNU General Public License on the World Wide
37  // Web at http://www.gnu.org/licenses/gpl.html.
38  //
39  //******************************************************************************
40  package edu.rit.pj.reduction;
41  
42  import java.io.Serial;
43  import java.util.concurrent.atomic.AtomicLong;
44  
45  /**
46   * Class SharedLong provides a reduction variable for a value of type
47   * <code>long</code>.
48   * <P>
49   * Class SharedLong is multiple thread safe. The methods use lock-free atomic
50   * compare-and-set.
51   * <P>
52   * <I>Note:</I> Class SharedLong is implemented using class
53   * java.util.concurrent.atomic.AtomicLong.
54   *
55   * @author Alan Kaminsky
56   * @version 07-Jun-2007
57   */
58  public class SharedLong
59          extends Number {
60  
61      @Serial
62      private static final long serialVersionUID = 1L;
63  
64  // Hidden data members.
65      private AtomicLong myValue;
66  
67  // Exported constructors.
68      /**
69       * Construct a new long reduction variable with the initial value 0.
70       */
71      public SharedLong() {
72          myValue = new AtomicLong();
73      }
74  
75      /**
76       * Construct a new long reduction variable with the given initial value.
77       *
78       * @param initialValue Initial value.
79       */
80      public SharedLong(long initialValue) {
81          myValue = new AtomicLong(initialValue);
82      }
83  
84  // Exported operations.
85      /**
86       * Returns this reduction variable's current value.
87       *
88       * @return Current value.
89       */
90      public long get() {
91          return myValue.get();
92      }
93  
94      /**
95       * Set this reduction variable to the given value.
96       *
97       * @param value New value.
98       */
99      public void set(long value) {
100         myValue.set(value);
101     }
102 
103     /**
104      * Set this reduction variable to the given value and return the previous
105      * value.
106      *
107      * @param value New value.
108      * @return Previous value.
109      */
110     public long getAndSet(long value) {
111         return myValue.getAndSet(value);
112     }
113 
114     /**
115      * Atomically set this reduction variable to the given updated value if the
116      * current value equals the expected value.
117      *
118      * @param expect Expected value.
119      * @param update Updated value.
120      * @return True if the update happened, false otherwise.
121      */
122     public boolean compareAndSet(long expect,
123             long update) {
124         return myValue.compareAndSet(expect, update);
125     }
126 
127     /**
128      * Atomically set this reduction variable to the given updated value if the
129      * current value equals the expected value. May fail spuriously.
130      *
131      * @param expect Expected value.
132      * @param update Updated value.
133      * @return True if the update happened, false otherwise.
134      */
135     @SuppressWarnings("deprecation")
136     public boolean weakCompareAndSet(long expect,
137             long update) {
138         return myValue.weakCompareAndSet(expect, update);
139     }
140 
141     /**
142      * Add one to this reduction variable and return the previous value.
143      *
144      * @return Previous value.
145      */
146     public long getAndIncrement() {
147         return myValue.getAndIncrement();
148     }
149 
150     /**
151      * Subtract one from this reduction variable and return the previous value.
152      *
153      * @return Previous value.
154      */
155     public long getAndDecrement() {
156         return myValue.getAndDecrement();
157     }
158 
159     /**
160      * Add the given value to this reduction variable and return the previous
161      * value.
162      *
163      * @param value Value to add.
164      * @return Previous value.
165      */
166     public long getAndAdd(long value) {
167         return myValue.getAndAdd(value);
168     }
169 
170     /**
171      * Add one to this reduction variable and return the new value.
172      *
173      * @return New value.
174      */
175     public long incrementAndGet() {
176         return myValue.incrementAndGet();
177     }
178 
179     /**
180      * Subtract one from this reduction variable and return the new value.
181      *
182      * @return New value.
183      */
184     public long decrementAndGet() {
185         return myValue.decrementAndGet();
186     }
187 
188     /**
189      * Add the given value to this reduction variable and return the new value.
190      *
191      * @param value Value to add.
192      * @return New value.
193      */
194     public long addAndGet(long value) {
195         return myValue.addAndGet(value);
196     }
197 
198     /**
199      * Combine this reduction variable with the given value using the given
200      * operation. The result is stored back into this reduction variable and is
201      * returned.
202      *
203      * @param value Value.
204      * @param op Binary operation.
205      * @return (This variable) <I>op</I> (<code>value</code>).
206      */
207     public long reduce(long value,
208             LongOp op) {
209         for (;;) {
210             long oldvalue = myValue.get();
211             long newvalue = op.op(oldvalue, value);
212             if (myValue.compareAndSet(oldvalue, newvalue)) {
213                 return newvalue;
214             }
215         }
216     }
217 
218     /**
219      * Returns a string version of this reduction variable.
220      *
221      * @return String version.
222      */
223     public String toString() {
224         return Long.toString(get());
225     }
226 
227     /**
228      * Returns this reduction variable's current value converted to type
229      * <code>int</code>.
230      *
231      * @return Current value.
232      */
233     public int intValue() {
234         return (int) get();
235     }
236 
237     /**
238      * Returns this reduction variable's current value converted to type
239      * <code>long</code>.
240      *
241      * @return Current value.
242      */
243     public long longValue() {
244         return get();
245     }
246 
247     /**
248      * Returns this reduction variable's current value converted to type
249      * <code>float</code>.
250      *
251      * @return Current value.
252      */
253     public float floatValue() {
254         return (float) get();
255     }
256 
257     /**
258      * Returns this reduction variable's current value converted to type
259      * <code>double</code>.
260      *
261      * @return Current value.
262      */
263     public double doubleValue() {
264         return (double) get();
265     }
266 
267 }