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