1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  * Other contributors include Andrew Wright, Jeffrey Hayes,
6  * Pat Fisher, Mike Judd.
7  */
8 
9 package jsr166;
10 
11 import java.util.concurrent.atomic.AtomicStampedReference;
12 
13 import junit.framework.Test;
14 import junit.framework.TestSuite;
15 
16 public class AtomicStampedReferenceTest extends JSR166TestCase {
17     // android-note: Removed because the CTS runner does a bad job of
18     // retrying tests that have suite() declarations.
19     //
20     // public static void main(String[] args) {
21     //     main(suite(), args);
22     // }
23     // public static Test suite() {
24     //     return new TestSuite(AtomicStampedReferenceTest.class);
25     // }
26 
27     /**
28      * constructor initializes to given reference and stamp
29      */
testConstructor()30     public void testConstructor() {
31         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
32         assertSame(one, ai.getReference());
33         assertEquals(0, ai.getStamp());
34         AtomicStampedReference a2 = new AtomicStampedReference(null, 1);
35         assertNull(a2.getReference());
36         assertEquals(1, a2.getStamp());
37     }
38 
39     /**
40      * get returns the last values of reference and stamp set
41      */
testGetSet()42     public void testGetSet() {
43         int[] mark = new int[1];
44         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
45         assertSame(one, ai.getReference());
46         assertEquals(0, ai.getStamp());
47         assertSame(one, ai.get(mark));
48         assertEquals(0, mark[0]);
49         ai.set(two, 0);
50         assertSame(two, ai.getReference());
51         assertEquals(0, ai.getStamp());
52         assertSame(two, ai.get(mark));
53         assertEquals(0, mark[0]);
54         ai.set(one, 1);
55         assertSame(one, ai.getReference());
56         assertEquals(1, ai.getStamp());
57         assertSame(one, ai.get(mark));
58         assertEquals(1, mark[0]);
59     }
60 
61     /**
62      * attemptStamp succeeds in single thread
63      */
testAttemptStamp()64     public void testAttemptStamp() {
65         int[] mark = new int[1];
66         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
67         assertEquals(0, ai.getStamp());
68         assertTrue(ai.attemptStamp(one, 1));
69         assertEquals(1, ai.getStamp());
70         assertSame(one, ai.get(mark));
71         assertEquals(1, mark[0]);
72     }
73 
74     /**
75      * compareAndSet succeeds in changing values if equal to expected reference
76      * and stamp else fails
77      */
testCompareAndSet()78     public void testCompareAndSet() {
79         int[] mark = new int[1];
80         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
81         assertSame(one, ai.get(mark));
82         assertEquals(0, ai.getStamp());
83         assertEquals(0, mark[0]);
84 
85         assertTrue(ai.compareAndSet(one, two, 0, 0));
86         assertSame(two, ai.get(mark));
87         assertEquals(0, mark[0]);
88 
89         assertTrue(ai.compareAndSet(two, m3, 0, 1));
90         assertSame(m3, ai.get(mark));
91         assertEquals(1, mark[0]);
92 
93         assertFalse(ai.compareAndSet(two, m3, 1, 1));
94         assertSame(m3, ai.get(mark));
95         assertEquals(1, mark[0]);
96     }
97 
98     /**
99      * compareAndSet in one thread enables another waiting for reference value
100      * to succeed
101      */
testCompareAndSetInMultipleThreads()102     public void testCompareAndSetInMultipleThreads() throws Exception {
103         final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
104         Thread t = new Thread(new CheckedRunnable() {
105             public void realRun() {
106                 while (!ai.compareAndSet(two, three, 0, 0))
107                     Thread.yield();
108             }});
109 
110         t.start();
111         assertTrue(ai.compareAndSet(one, two, 0, 0));
112         t.join(LONG_DELAY_MS);
113         assertFalse(t.isAlive());
114         assertSame(three, ai.getReference());
115         assertEquals(0, ai.getStamp());
116     }
117 
118     /**
119      * compareAndSet in one thread enables another waiting for stamp value
120      * to succeed
121      */
testCompareAndSetInMultipleThreads2()122     public void testCompareAndSetInMultipleThreads2() throws Exception {
123         final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
124         Thread t = new Thread(new CheckedRunnable() {
125             public void realRun() {
126                 while (!ai.compareAndSet(one, one, 1, 2))
127                     Thread.yield();
128             }});
129 
130         t.start();
131         assertTrue(ai.compareAndSet(one, one, 0, 1));
132         t.join(LONG_DELAY_MS);
133         assertFalse(t.isAlive());
134         assertSame(one, ai.getReference());
135         assertEquals(2, ai.getStamp());
136     }
137 
138     /**
139      * repeated weakCompareAndSet succeeds in changing values when equal
140      * to expected
141      */
testWeakCompareAndSet()142     public void testWeakCompareAndSet() {
143         int[] mark = new int[1];
144         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
145         assertSame(one, ai.get(mark));
146         assertEquals(0, ai.getStamp());
147         assertEquals(0, mark[0]);
148 
149         do {} while (!ai.weakCompareAndSet(one, two, 0, 0));
150         assertSame(two, ai.get(mark));
151         assertEquals(0, mark[0]);
152 
153         do {} while (!ai.weakCompareAndSet(two, m3, 0, 1));
154         assertSame(m3, ai.get(mark));
155         assertEquals(1, mark[0]);
156     }
157 
158 }
159