1
2
3
4
5
6
7
8
9
10
11
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 }