View Javadoc

1   /*
2     File: SynchronizedRef.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    11Jun1998  dl               Create public version
12  */
13  
14  package org.jdiagnose.concurrent;
15  
16  /***
17   * A simple class maintaining a single reference variable that
18   * is always accessed and updated under synchronization.
19   * <p>
20   * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
21   **/
22  
23  public class SynchronizedRef extends SynchronizedVariable {
24    /*** The maintained reference **/
25    protected Object value_;
26  
27    /*** 
28     * Create a SynchronizedRef initially holding the given reference 
29     * and using its own internal lock.
30     **/
31    public SynchronizedRef(Object initialValue) { 
32      super();
33      value_ = initialValue; 
34    }
35  
36    /*** 
37     * Make a new SynchronizedRef with the given initial value,
38     * and using the supplied lock.
39     **/
40    public SynchronizedRef(Object initialValue, Object lock) { 
41      super(lock); 
42      value_ = initialValue; 
43    }
44  
45    /*** 
46     * Return the current value 
47     **/
48    public final Object get() { synchronized(lock_) { return value_; } }
49  
50    /*** 
51     * Set to newValue.
52     * @return the old value 
53     **/
54  
55    public Object set(Object newValue) { 
56      synchronized (lock_) {
57        Object old = value_;
58        value_ = newValue; 
59        return old;
60      }
61    }
62  
63    /***
64     * Set value to newValue only if it is currently assumedValue.
65     * @return true if successful
66     **/
67    public boolean commit(Object assumedValue, Object newValue) {
68      synchronized(lock_) {
69        boolean success = (assumedValue == value_);
70        if (success) value_ = newValue;
71        return success;
72      }
73    }
74  
75  
76    /*** 
77     * Atomically swap values with another SynchronizedRef.
78     * Uses identityHashCode to avoid deadlock when
79     * two SynchronizedRefs attempt to simultaneously swap with each other.
80     * (Note: Ordering via identyHashCode is not strictly guaranteed
81     * by the language specification to return unique, orderable
82     * values, but in practice JVMs rely on them being unique.)
83     * @return the new value 
84     **/
85  
86    public Object swap(SynchronizedRef other) {
87      if (other == this) return get();
88      SynchronizedRef fst = this;
89      SynchronizedRef snd = other;
90      if (System.identityHashCode(fst) > System.identityHashCode(snd)) {
91        fst = other;
92        snd = this;
93      }
94      synchronized(fst.lock_) {
95        synchronized(snd.lock_) {
96          fst.set(snd.set(fst.get()));
97          return get();
98        }
99      }
100   }
101 
102 
103 }