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 junit.framework.*;
12 import java.util.concurrent.atomic.AtomicStampedReference;
13 
14 public class AtomicStampedReferenceTest extends JSR166TestCase {
15 
16     /**
17      * constructor initializes to given reference and stamp
18      */
testConstructor()19     public void testConstructor() {
20         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
21         assertSame(one, ai.getReference());
22         assertEquals(0, ai.getStamp());
23         AtomicStampedReference a2 = new AtomicStampedReference(null, 1);
24         assertNull(a2.getReference());
25         assertEquals(1, a2.getStamp());
26     }
27 
28     /**
29      * get returns the last values of reference and stamp set
30      */
testGetSet()31     public void testGetSet() {
32         int[] mark = new int[1];
33         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
34         assertSame(one, ai.getReference());
35         assertEquals(0, ai.getStamp());
36         assertSame(one, ai.get(mark));
37         assertEquals(0, mark[0]);
38         ai.set(two, 0);
39         assertSame(two, ai.getReference());
40         assertEquals(0, ai.getStamp());
41         assertSame(two, ai.get(mark));
42         assertEquals(0, mark[0]);
43         ai.set(one, 1);
44         assertSame(one, ai.getReference());
45         assertEquals(1, ai.getStamp());
46         assertSame(one, ai.get(mark));
47         assertEquals(1, mark[0]);
48     }
49 
50     /**
51      * attemptStamp succeeds in single thread
52      */
testAttemptStamp()53     public void testAttemptStamp() {
54         int[] mark = new int[1];
55         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
56         assertEquals(0, ai.getStamp());
57         assertTrue(ai.attemptStamp(one, 1));
58         assertEquals(1, ai.getStamp());
59         assertSame(one, ai.get(mark));
60         assertEquals(1, mark[0]);
61     }
62 
63     /**
64      * compareAndSet succeeds in changing values if equal to expected reference
65      * and stamp else fails
66      */
testCompareAndSet()67     public void testCompareAndSet() {
68         int[] mark = new int[1];
69         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
70         assertSame(one, ai.get(mark));
71         assertEquals(0, ai.getStamp());
72         assertEquals(0, mark[0]);
73 
74         assertTrue(ai.compareAndSet(one, two, 0, 0));
75         assertSame(two, ai.get(mark));
76         assertEquals(0, mark[0]);
77 
78         assertTrue(ai.compareAndSet(two, m3, 0, 1));
79         assertSame(m3, ai.get(mark));
80         assertEquals(1, mark[0]);
81 
82         assertFalse(ai.compareAndSet(two, m3, 1, 1));
83         assertSame(m3, ai.get(mark));
84         assertEquals(1, mark[0]);
85     }
86 
87     /**
88      * compareAndSet in one thread enables another waiting for reference value
89      * to succeed
90      */
testCompareAndSetInMultipleThreads()91     public void testCompareAndSetInMultipleThreads() throws Exception {
92         final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
93         Thread t = new Thread(new CheckedRunnable() {
94             public void realRun() {
95                 while (!ai.compareAndSet(two, three, 0, 0))
96                     Thread.yield();
97             }});
98 
99         t.start();
100         assertTrue(ai.compareAndSet(one, two, 0, 0));
101         t.join(LONG_DELAY_MS);
102         assertFalse(t.isAlive());
103         assertSame(three, ai.getReference());
104         assertEquals(0, ai.getStamp());
105     }
106 
107     /**
108      * compareAndSet in one thread enables another waiting for stamp value
109      * to succeed
110      */
testCompareAndSetInMultipleThreads2()111     public void testCompareAndSetInMultipleThreads2() throws Exception {
112         final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
113         Thread t = new Thread(new CheckedRunnable() {
114             public void realRun() {
115                 while (!ai.compareAndSet(one, one, 1, 2))
116                     Thread.yield();
117             }});
118 
119         t.start();
120         assertTrue(ai.compareAndSet(one, one, 0, 1));
121         t.join(LONG_DELAY_MS);
122         assertFalse(t.isAlive());
123         assertSame(one, ai.getReference());
124         assertEquals(2, ai.getStamp());
125     }
126 
127     /**
128      * repeated weakCompareAndSet succeeds in changing values when equal
129      * to expected
130      */
testWeakCompareAndSet()131     public void testWeakCompareAndSet() {
132         int[] mark = new int[1];
133         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
134         assertSame(one, ai.get(mark));
135         assertEquals(0, ai.getStamp());
136         assertEquals(0, mark[0]);
137 
138         while (!ai.weakCompareAndSet(one, two, 0, 0));
139         assertSame(two, ai.get(mark));
140         assertEquals(0, mark[0]);
141 
142         while (!ai.weakCompareAndSet(two, m3, 0, 1));
143         assertSame(m3, ai.get(mark));
144         assertEquals(1, mark[0]);
145     }
146 
147 }
148