1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea with assistance from members of JCP JSR-166 30 * Expert Group and released to the public domain, as explained at 31 * http://creativecommons.org/publicdomain/zero/1.0/ 32 * Other contributors include Andrew Wright, Jeffrey Hayes, 33 * Pat Fisher, Mike Judd. 34 */ 35 36 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; 37 38 import junit.framework.Test; 39 import junit.framework.TestSuite; 40 41 public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase { 42 volatile Integer x = null; 43 protected volatile Integer protectedField; 44 private volatile Integer privateField; 45 Object z; 46 Integer w; 47 volatile int i; 48 main(String[] args)49 public static void main(String[] args) { 50 main(suite(), args); 51 } suite()52 public static Test suite() { 53 return new TestSuite(AtomicReferenceFieldUpdaterTest.class); 54 } 55 updaterFor(String fieldName)56 static AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) { 57 return AtomicReferenceFieldUpdater.newUpdater 58 (AtomicReferenceFieldUpdaterTest.class, Integer.class, fieldName); 59 } 60 61 /** 62 * Construction with non-existent field throws RuntimeException 63 */ testConstructor()64 public void testConstructor() { 65 try { 66 updaterFor("y"); 67 shouldThrow(); 68 } catch (RuntimeException success) { 69 assertNotNull(success.getCause()); 70 } 71 } 72 73 /** 74 * construction with field not of given type throws ClassCastException 75 */ testConstructor2()76 public void testConstructor2() { 77 try { 78 updaterFor("z"); 79 shouldThrow(); 80 } catch (ClassCastException success) {} 81 } 82 83 /** 84 * Constructor with non-volatile field throws IllegalArgumentException 85 */ testConstructor3()86 public void testConstructor3() { 87 try { 88 updaterFor("w"); 89 shouldThrow(); 90 } catch (IllegalArgumentException success) {} 91 } 92 93 /** 94 * Constructor with non-reference field throws ClassCastException 95 */ testConstructor4()96 public void testConstructor4() { 97 try { 98 updaterFor("i"); 99 shouldThrow(); 100 } catch (ClassCastException success) {} 101 } 102 103 /** 104 * construction using private field from subclass throws RuntimeException 105 */ testPrivateFieldInSubclass()106 public void testPrivateFieldInSubclass() { 107 new NonNestmates.AtomicReferenceFieldUpdaterTestSubclass() 108 .checkPrivateAccess(); 109 } 110 111 /** 112 * construction from unrelated class; package access is allowed, 113 * private access is not 114 */ testUnrelatedClassAccess()115 public void testUnrelatedClassAccess() { 116 new NonNestmates().checkPackageAccess(this); 117 new NonNestmates().checkPrivateAccess(this); 118 } 119 120 /** 121 * get returns the last value set or assigned 122 */ testGetSet()123 public void testGetSet() { 124 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; 125 a = updaterFor("x"); 126 x = one; 127 assertSame(one, a.get(this)); 128 a.set(this, two); 129 assertSame(two, a.get(this)); 130 a.set(this, m3); 131 assertSame(m3, a.get(this)); 132 } 133 134 /** 135 * get returns the last value lazySet by same thread 136 */ testGetLazySet()137 public void testGetLazySet() { 138 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; 139 a = updaterFor("x"); 140 x = one; 141 assertSame(one, a.get(this)); 142 a.lazySet(this, two); 143 assertSame(two, a.get(this)); 144 a.lazySet(this, m3); 145 assertSame(m3, a.get(this)); 146 } 147 148 /** 149 * compareAndSet succeeds in changing value if same as expected else fails 150 */ testCompareAndSet()151 public void testCompareAndSet() { 152 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; 153 a = updaterFor("x"); 154 x = one; 155 assertTrue(a.compareAndSet(this, one, two)); 156 assertTrue(a.compareAndSet(this, two, m4)); 157 assertSame(m4, a.get(this)); 158 assertFalse(a.compareAndSet(this, m5, seven)); 159 assertNotSame(seven, a.get(this)); 160 assertTrue(a.compareAndSet(this, m4, seven)); 161 assertSame(seven, a.get(this)); 162 } 163 164 /** 165 * compareAndSet succeeds in changing protected field value if 166 * same as expected else fails 167 */ testCompareAndSetProtectedInSubclass()168 public void testCompareAndSetProtectedInSubclass() { 169 new NonNestmates.AtomicReferenceFieldUpdaterTestSubclass() 170 .checkCompareAndSetProtectedSub(); 171 } 172 173 /** 174 * compareAndSet in one thread enables another waiting for value 175 * to succeed 176 */ testCompareAndSetInMultipleThreads()177 public void testCompareAndSetInMultipleThreads() throws Exception { 178 x = one; 179 final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; 180 a = updaterFor("x"); 181 182 Thread t = new Thread(new CheckedRunnable() { 183 public void realRun() { 184 while (!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three)) 185 Thread.yield(); 186 }}); 187 188 t.start(); 189 assertTrue(a.compareAndSet(this, one, two)); 190 t.join(LONG_DELAY_MS); 191 assertFalse(t.isAlive()); 192 assertSame(three, a.get(this)); 193 } 194 195 /** 196 * repeated weakCompareAndSet succeeds in changing value when same as expected 197 */ testWeakCompareAndSet()198 public void testWeakCompareAndSet() { 199 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; 200 a = updaterFor("x"); 201 x = one; 202 do {} while (!a.weakCompareAndSet(this, one, two)); 203 do {} while (!a.weakCompareAndSet(this, two, m4)); 204 assertSame(m4, a.get(this)); 205 do {} while (!a.weakCompareAndSet(this, m4, seven)); 206 assertSame(seven, a.get(this)); 207 } 208 209 /** 210 * getAndSet returns previous value and sets to given value 211 */ testGetAndSet()212 public void testGetAndSet() { 213 AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; 214 a = updaterFor("x"); 215 x = one; 216 assertSame(one, a.getAndSet(this, zero)); 217 assertSame(zero, a.getAndSet(this, m10)); 218 assertSame(m10, a.getAndSet(this, 1)); 219 } 220 221 } 222