Home | History | Annotate | Download | only in jsr166
      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.AtomicIntegerFieldUpdater;
     12 
     13 import junit.framework.Test;
     14 import junit.framework.TestSuite;
     15 
     16 public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase {
     17     volatile int x = 0;
     18     protected volatile int protectedField;
     19     private volatile int privateField;
     20     int w;
     21     float z;
     22     // 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(AtomicIntegerFieldUpdaterTest.class);
     30     // }
     31 
     32     // for testing subclass access
     33     // android-note: Removed because android doesn't restrict reflection access
     34     // static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest {
     35     //     public void checkPrivateAccess() {
     36     //         try {
     37     //             AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
     38     //                 AtomicIntegerFieldUpdater.newUpdater
     39     //                 (AtomicIntegerFieldUpdaterTest.class, "privateField");
     40     //             shouldThrow();
     41     //         } catch (RuntimeException success) {
     42     //             assertNotNull(success.getCause());
     43     //         }
     44     //     }
     45 
     46     //     public void checkCompareAndSetProtectedSub() {
     47     //         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
     48     //             AtomicIntegerFieldUpdater.newUpdater
     49     //             (AtomicIntegerFieldUpdaterTest.class, "protectedField");
     50     //         this.protectedField = 1;
     51     //         assertTrue(a.compareAndSet(this, 1, 2));
     52     //         assertTrue(a.compareAndSet(this, 2, -4));
     53     //         assertEquals(-4, a.get(this));
     54     //         assertFalse(a.compareAndSet(this, -5, 7));
     55     //         assertEquals(-4, a.get(this));
     56     //         assertTrue(a.compareAndSet(this, -4, 7));
     57     //         assertEquals(7, a.get(this));
     58     //     }
     59     // }
     60 
     61     // static class UnrelatedClass {
     62     //     public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) {
     63     //         obj.x = 72;
     64     //         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
     65     //             AtomicIntegerFieldUpdater.newUpdater
     66     //             (AtomicIntegerFieldUpdaterTest.class, "x");
     67     //         assertEquals(72, a.get(obj));
     68     //         assertTrue(a.compareAndSet(obj, 72, 73));
     69     //         assertEquals(73, a.get(obj));
     70     //     }
     71 
     72     //     public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) {
     73     //         try {
     74     //             AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
     75     //                 AtomicIntegerFieldUpdater.newUpdater
     76     //                 (AtomicIntegerFieldUpdaterTest.class, "privateField");
     77     //             throw new AssertionError("should throw");
     78     //         } catch (RuntimeException success) {
     79     //             assertNotNull(success.getCause());
     80     //         }
     81     //     }
     82     // }
     83 
     84     AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) {
     85         return AtomicIntegerFieldUpdater.newUpdater
     86             (AtomicIntegerFieldUpdaterTest.class, fieldName);
     87     }
     88 
     89     /**
     90      * Construction with non-existent field throws RuntimeException
     91      */
     92     public void testConstructor() {
     93         try {
     94             updaterFor("y");
     95             shouldThrow();
     96         } catch (RuntimeException success) {
     97             assertNotNull(success.getCause());
     98         }
     99     }
    100 
    101     /**
    102      * construction with field not of given type throws IllegalArgumentException
    103      */
    104     public void testConstructor2() {
    105         try {
    106             updaterFor("z");
    107             shouldThrow();
    108         } catch (IllegalArgumentException success) {}
    109     }
    110 
    111     /**
    112      * construction with non-volatile field throws IllegalArgumentException
    113      */
    114     public void testConstructor3() {
    115         try {
    116             updaterFor("w");
    117             shouldThrow();
    118         } catch (IllegalArgumentException success) {}
    119     }
    120 
    121     /**
    122      * construction using private field from subclass throws RuntimeException
    123      */
    124     // android-note: Removed because android doesn't restrict reflection access
    125     // public void testPrivateFieldInSubclass() {
    126     //     AtomicIntegerFieldUpdaterTestSubclass s =
    127     //         new AtomicIntegerFieldUpdaterTestSubclass();
    128     //     s.checkPrivateAccess();
    129     // }
    130 
    131     /**
    132      * construction from unrelated class; package access is allowed,
    133      * private access is not
    134      */
    135     // android-note: Removed because android doesn't restrict reflection access
    136     // public void testUnrelatedClassAccess() {
    137     //     new UnrelatedClass().checkPackageAccess(this);
    138     //     new UnrelatedClass().checkPrivateAccess(this);
    139     // }
    140 
    141     /**
    142      * get returns the last value set or assigned
    143      */
    144     public void testGetSet() {
    145         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    146         a = updaterFor("x");
    147         x = 1;
    148         assertEquals(1, a.get(this));
    149         a.set(this, 2);
    150         assertEquals(2, a.get(this));
    151         a.set(this, -3);
    152         assertEquals(-3, a.get(this));
    153     }
    154 
    155     /**
    156      * get returns the last value lazySet by same thread
    157      */
    158     public void testGetLazySet() {
    159         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    160         a = updaterFor("x");
    161         x = 1;
    162         assertEquals(1, a.get(this));
    163         a.lazySet(this, 2);
    164         assertEquals(2, a.get(this));
    165         a.lazySet(this, -3);
    166         assertEquals(-3, a.get(this));
    167     }
    168 
    169     /**
    170      * compareAndSet succeeds in changing value if equal to expected else fails
    171      */
    172     public void testCompareAndSet() {
    173         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    174         a = updaterFor("x");
    175         x = 1;
    176         assertTrue(a.compareAndSet(this, 1, 2));
    177         assertTrue(a.compareAndSet(this, 2, -4));
    178         assertEquals(-4, a.get(this));
    179         assertFalse(a.compareAndSet(this, -5, 7));
    180         assertEquals(-4, a.get(this));
    181         assertTrue(a.compareAndSet(this, -4, 7));
    182         assertEquals(7, a.get(this));
    183     }
    184 
    185     /**
    186      * compareAndSet succeeds in changing protected field value if
    187      * equal to expected else fails
    188      */
    189     public void testCompareAndSetProtected() {
    190         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    191         a = updaterFor("protectedField");
    192         protectedField = 1;
    193         assertTrue(a.compareAndSet(this, 1, 2));
    194         assertTrue(a.compareAndSet(this, 2, -4));
    195         assertEquals(-4, a.get(this));
    196         assertFalse(a.compareAndSet(this, -5, 7));
    197         assertEquals(-4, a.get(this));
    198         assertTrue(a.compareAndSet(this, -4, 7));
    199         assertEquals(7, a.get(this));
    200     }
    201 
    202     /**
    203      * compareAndSet succeeds in changing protected field value if
    204      * equal to expected else fails
    205      */
    206     // android-note: Removed because android doesn't restrict reflection access
    207     // public void testCompareAndSetProtectedInSubclass() {
    208     //     AtomicIntegerFieldUpdaterTestSubclass s =
    209     //         new AtomicIntegerFieldUpdaterTestSubclass();
    210     //     s.checkCompareAndSetProtectedSub();
    211     // }
    212 
    213     /**
    214      * compareAndSet in one thread enables another waiting for value
    215      * to succeed
    216      */
    217     public void testCompareAndSetInMultipleThreads() throws Exception {
    218         x = 1;
    219         final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    220         a = updaterFor("x");
    221 
    222         Thread t = new Thread(new CheckedRunnable() {
    223             public void realRun() {
    224                 while (!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3))
    225                     Thread.yield();
    226             }});
    227 
    228         t.start();
    229         assertTrue(a.compareAndSet(this, 1, 2));
    230         t.join(LONG_DELAY_MS);
    231         assertFalse(t.isAlive());
    232         assertEquals(3, a.get(this));
    233     }
    234 
    235     /**
    236      * repeated weakCompareAndSet succeeds in changing value when equal
    237      * to expected
    238      */
    239     public void testWeakCompareAndSet() {
    240         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    241         a = updaterFor("x");
    242         x = 1;
    243         do {} while (!a.weakCompareAndSet(this, 1, 2));
    244         do {} while (!a.weakCompareAndSet(this, 2, -4));
    245         assertEquals(-4, a.get(this));
    246         do {} while (!a.weakCompareAndSet(this, -4, 7));
    247         assertEquals(7, a.get(this));
    248     }
    249 
    250     /**
    251      * getAndSet returns previous value and sets to given value
    252      */
    253     public void testGetAndSet() {
    254         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    255         a = updaterFor("x");
    256         x = 1;
    257         assertEquals(1, a.getAndSet(this, 0));
    258         assertEquals(0, a.getAndSet(this, -10));
    259         assertEquals(-10, a.getAndSet(this, 1));
    260     }
    261 
    262     /**
    263      * getAndAdd returns previous value and adds given value
    264      */
    265     public void testGetAndAdd() {
    266         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    267         a = updaterFor("x");
    268         x = 1;
    269         assertEquals(1, a.getAndAdd(this, 2));
    270         assertEquals(3, a.get(this));
    271         assertEquals(3, a.getAndAdd(this, -4));
    272         assertEquals(-1, a.get(this));
    273     }
    274 
    275     /**
    276      * getAndDecrement returns previous value and decrements
    277      */
    278     public void testGetAndDecrement() {
    279         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    280         a = updaterFor("x");
    281         x = 1;
    282         assertEquals(1, a.getAndDecrement(this));
    283         assertEquals(0, a.getAndDecrement(this));
    284         assertEquals(-1, a.getAndDecrement(this));
    285     }
    286 
    287     /**
    288      * getAndIncrement returns previous value and increments
    289      */
    290     public void testGetAndIncrement() {
    291         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    292         a = updaterFor("x");
    293         x = 1;
    294         assertEquals(1, a.getAndIncrement(this));
    295         assertEquals(2, a.get(this));
    296         a.set(this, -2);
    297         assertEquals(-2, a.getAndIncrement(this));
    298         assertEquals(-1, a.getAndIncrement(this));
    299         assertEquals(0, a.getAndIncrement(this));
    300         assertEquals(1, a.get(this));
    301     }
    302 
    303     /**
    304      * addAndGet adds given value to current, and returns current value
    305      */
    306     public void testAddAndGet() {
    307         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    308         a = updaterFor("x");
    309         x = 1;
    310         assertEquals(3, a.addAndGet(this, 2));
    311         assertEquals(3, a.get(this));
    312         assertEquals(-1, a.addAndGet(this, -4));
    313         assertEquals(-1, a.get(this));
    314     }
    315 
    316     /**
    317      * decrementAndGet decrements and returns current value
    318      */
    319     public void testDecrementAndGet() {
    320         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    321         a = updaterFor("x");
    322         x = 1;
    323         assertEquals(0, a.decrementAndGet(this));
    324         assertEquals(-1, a.decrementAndGet(this));
    325         assertEquals(-2, a.decrementAndGet(this));
    326         assertEquals(-2, a.get(this));
    327     }
    328 
    329     /**
    330      * incrementAndGet increments and returns current value
    331      */
    332     public void testIncrementAndGet() {
    333         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    334         a = updaterFor("x");
    335         x = 1;
    336         assertEquals(2, a.incrementAndGet(this));
    337         assertEquals(2, a.get(this));
    338         a.set(this, -2);
    339         assertEquals(-1, a.incrementAndGet(this));
    340         assertEquals(0, a.incrementAndGet(this));
    341         assertEquals(1, a.incrementAndGet(this));
    342         assertEquals(1, a.get(this));
    343     }
    344 
    345 }
    346