KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > concurrent > atomic > AtomicMarkableReference


1 /*
2  * @(#)AtomicMarkableReference.java 1.4 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.concurrent.atomic;
9
10 /**
11  * An <tt>AtomicMarkableReference</tt> maintains an object reference
12  * along with a mark bit, that can be updated atomically.
13  * <p>
14  * <p> Implementation note. This implementation maintains markable
15  * references by creating internal objects representing "boxed"
16  * [reference, boolean] pairs.
17  *
18  * @since 1.5
19  * @author Doug Lea
20  * @param <V> The type of object referred to by this reference
21  */

22 public class AtomicMarkableReference<V> {
23
24     private static class ReferenceBooleanPair<T> {
25         private final T reference;
26         private final boolean bit;
27         ReferenceBooleanPair(T r, boolean i) {
28             reference = r; bit = i;
29         }
30     }
31
32     private final AtomicReference JavaDoc<ReferenceBooleanPair<V>> atomicRef;
33
34     /**
35      * Creates a new <tt>AtomicMarkableReference</tt> with the given
36      * initial values.
37      *
38      * @param initialRef the initial reference
39      * @param initialMark the initial mark
40      */

41     public AtomicMarkableReference(V initialRef, boolean initialMark) {
42         atomicRef = new AtomicReference JavaDoc<ReferenceBooleanPair<V>> (new ReferenceBooleanPair<V>(initialRef, initialMark));
43     }
44
45     /**
46      * Returns the current value of the reference.
47      *
48      * @return the current value of the reference
49      */

50     public V getReference() {
51         return atomicRef.get().reference;
52     }
53
54     /**
55      * Returns the current value of the mark.
56      *
57      * @return the current value of the mark
58      */

59     public boolean isMarked() {
60         return atomicRef.get().bit;
61     }
62
63     /**
64      * Returns the current values of both the reference and the mark.
65      * Typical usage is <tt>boolean[1] holder; ref = v.get(holder); </tt>.
66      *
67      * @param markHolder an array of size of at least one. On return,
68      * <tt>markholder[0]</tt> will hold the value of the mark.
69      * @return the current value of the reference
70      */

71     public V get(boolean[] markHolder) {
72         ReferenceBooleanPair<V> p = atomicRef.get();
73         markHolder[0] = p.bit;
74         return p.reference;
75     }
76
77     /**
78      * Atomically sets the value of both the reference and mark
79      * to the given update values if the
80      * current reference is <tt>==</tt> to the expected reference
81      * and the current mark is equal to the expected mark. Any given
82      * invocation of this operation may fail (return
83      * <tt>false</tt>) spuriously, but repeated invocation when
84      * the current value holds the expected value and no other thread
85      * is also attempting to set the value will eventually succeed.
86      *
87      * @param expectedReference the expected value of the reference
88      * @param newReference the new value for the reference
89      * @param expectedMark the expected value of the mark
90      * @param newMark the new value for the mark
91      * @return true if successful
92      */

93     public boolean weakCompareAndSet(V expectedReference,
94                                      V newReference,
95                                      boolean expectedMark,
96                                      boolean newMark) {
97         ReferenceBooleanPair current = atomicRef.get();
98         return expectedReference == current.reference &&
99             expectedMark == current.bit &&
100             ((newReference == current.reference && newMark == current.bit) ||
101              atomicRef.weakCompareAndSet(current,
102                                      new ReferenceBooleanPair<V>(newReference,
103                                                               newMark)));
104     }
105
106     /**
107      * Atomically sets the value of both the reference and mark
108      * to the given update values if the
109      * current reference is <tt>==</tt> to the expected reference
110      * and the current mark is equal to the expected mark.
111      *
112      * @param expectedReference the expected value of the reference
113      * @param newReference the new value for the reference
114      * @param expectedMark the expected value of the mark
115      * @param newMark the new value for the mark
116      * @return true if successful
117      */

118     public boolean compareAndSet(V expectedReference,
119                                  V newReference,
120                                  boolean expectedMark,
121                                  boolean newMark) {
122         ReferenceBooleanPair current = atomicRef.get();
123         return expectedReference == current.reference &&
124             expectedMark == current.bit &&
125             ((newReference == current.reference && newMark == current.bit) ||
126              atomicRef.compareAndSet(current,
127                                      new ReferenceBooleanPair<V>(newReference,
128                                                               newMark)));
129     }
130
131     /**
132      * Unconditionally sets the value of both the reference and mark.
133      *
134      * @param newReference the new value for the reference
135      * @param newMark the new value for the mark
136      */

137     public void set(V newReference, boolean newMark) {
138         ReferenceBooleanPair current = atomicRef.get();
139         if (newReference != current.reference || newMark != current.bit)
140             atomicRef.set(new ReferenceBooleanPair<V>(newReference, newMark));
141     }
142
143     /**
144      * Atomically sets the value of the mark to the given update value
145      * if the current reference is <tt>==</tt> to the expected
146      * reference. Any given invocation of this operation may fail
147      * (return <tt>false</tt>) spuriously, but repeated invocation
148      * when the current value holds the expected value and no other
149      * thread is also attempting to set the value will eventually
150      * succeed.
151      *
152      * @param expectedReference the expected value of the reference
153      * @param newMark the new value for the mark
154      * @return true if successful
155      */

156     public boolean attemptMark(V expectedReference, boolean newMark) {
157         ReferenceBooleanPair current = atomicRef.get();
158         return expectedReference == current.reference &&
159             (newMark == current.bit ||
160              atomicRef.compareAndSet
161              (current, new ReferenceBooleanPair<V>(expectedReference,
162                                                 newMark)));
163     }
164 }
165
Popular Tags