blob: 4b0d946d1d0a10e7add23e3679abf0b40d932869 [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
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
9package jsr166;
10
Calin Juravle8f0d92b2013-08-01 17:26:00 +010011import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
12
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010013import junit.framework.Test;
14import junit.framework.TestSuite;
15
Calin Juravle8f0d92b2013-08-01 17:26:00 +010016public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase {
17 volatile Integer x = null;
18 Object z;
19 Integer w;
20 volatile int i;
21
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010022 // android-note: Removed because the CTS runner does a bad job of
23 // retrying tests that have suite() declarations.
24 //
25 // public static void main(String[] args) {
26 // main(suite(), args);
27 // }
28 // public static Test suite() {
29 // return new TestSuite(...);
30 // }
31
Calin Juravle8f0d92b2013-08-01 17:26:00 +010032 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) {
33 return AtomicReferenceFieldUpdater.newUpdater
34 (AtomicReferenceFieldUpdaterTest.class, Integer.class, fieldName);
35 }
36
37 /**
38 * Construction with non-existent field throws RuntimeException
39 */
40 public void testConstructor() {
41 try {
42 updaterFor("y");
43 shouldThrow();
44 } catch (RuntimeException success) {
45 assertNotNull(success.getCause());
46 }
47 }
48
49 /**
50 * construction with field not of given type throws ClassCastException
51 */
52 public void testConstructor2() {
53 try {
54 updaterFor("z");
55 shouldThrow();
56 } catch (ClassCastException success) {}
57 }
58
59 /**
60 * Constructor with non-volatile field throws IllegalArgumentException
61 */
62 public void testConstructor3() {
63 try {
64 updaterFor("w");
65 shouldThrow();
66 } catch (IllegalArgumentException success) {}
67 }
68
69 /**
70 * Constructor with non-reference field throws ClassCastException
71 */
72 public void testConstructor4() {
73 try {
74 updaterFor("i");
75 shouldThrow();
76 } catch (ClassCastException success) {}
77 }
78
79 /**
80 * get returns the last value set or assigned
81 */
82 public void testGetSet() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010083 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010084 a = updaterFor("x");
85 x = one;
86 assertSame(one, a.get(this));
87 a.set(this, two);
88 assertSame(two, a.get(this));
89 a.set(this, m3);
90 assertSame(m3, a.get(this));
91 }
92
93 /**
94 * get returns the last value lazySet by same thread
95 */
96 public void testGetLazySet() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010097 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010098 a = updaterFor("x");
99 x = one;
100 assertSame(one, a.get(this));
101 a.lazySet(this, two);
102 assertSame(two, a.get(this));
103 a.lazySet(this, m3);
104 assertSame(m3, a.get(this));
105 }
106
107 /**
108 * compareAndSet succeeds in changing value if equal to expected else fails
109 */
110 public void testCompareAndSet() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100111 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100112 a = updaterFor("x");
113 x = one;
114 assertTrue(a.compareAndSet(this, one, two));
115 assertTrue(a.compareAndSet(this, two, m4));
116 assertSame(m4, a.get(this));
117 assertFalse(a.compareAndSet(this, m5, seven));
118 assertFalse(seven == a.get(this));
119 assertTrue(a.compareAndSet(this, m4, seven));
120 assertSame(seven, a.get(this));
121 }
122
123 /**
124 * compareAndSet in one thread enables another waiting for value
125 * to succeed
126 */
127 public void testCompareAndSetInMultipleThreads() throws Exception {
128 x = one;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100129 final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100130 a = updaterFor("x");
131
132 Thread t = new Thread(new CheckedRunnable() {
133 public void realRun() {
134 while (!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three))
135 Thread.yield();
136 }});
137
138 t.start();
139 assertTrue(a.compareAndSet(this, one, two));
140 t.join(LONG_DELAY_MS);
141 assertFalse(t.isAlive());
142 assertSame(three, a.get(this));
143 }
144
145 /**
146 * repeated weakCompareAndSet succeeds in changing value when equal
147 * to expected
148 */
149 public void testWeakCompareAndSet() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100150 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100151 a = updaterFor("x");
152 x = one;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100153 do {} while (!a.weakCompareAndSet(this, one, two));
154 do {} while (!a.weakCompareAndSet(this, two, m4));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100155 assertSame(m4, a.get(this));
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100156 do {} while (!a.weakCompareAndSet(this, m4, seven));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100157 assertSame(seven, a.get(this));
158 }
159
160 /**
161 * getAndSet returns previous value and sets to given value
162 */
163 public void testGetAndSet() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100164 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100165 a = updaterFor("x");
166 x = one;
167 assertSame(one, a.getAndSet(this, zero));
168 assertSame(zero, a.getAndSet(this, m10));
169 assertSame(m10, a.getAndSet(this, 1));
170 }
171
172}