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     int w;
     19     long z;
     20     // android-note: Removed because the CTS runner does a bad job of
     21     // retrying tests that have suite() declarations.
     22     //
     23     // public static void main(String[] args) {
     24     //     main(suite(), args);
     25     // }
     26     // public static Test suite() {
     27     //     return new TestSuite(...);
     28     // }
     29 
     30     AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) {
     31         return AtomicIntegerFieldUpdater.newUpdater
     32             (AtomicIntegerFieldUpdaterTest.class, fieldName);
     33     }
     34 
     35     /**
     36      * Construction with non-existent field throws RuntimeException
     37      */
     38     public void testConstructor() {
     39         try {
     40             updaterFor("y");
     41             shouldThrow();
     42         } catch (RuntimeException success) {
     43             assertNotNull(success.getCause());
     44         }
     45     }
     46 
     47     /**
     48      * construction with field not of given type throws IllegalArgumentException
     49      */
     50     public void testConstructor2() {
     51         try {
     52             updaterFor("z");
     53             shouldThrow();
     54         } catch (IllegalArgumentException success) {}
     55     }
     56 
     57     /**
     58      * construction with non-volatile field throws IllegalArgumentException
     59      */
     60     public void testConstructor3() {
     61         try {
     62             updaterFor("w");
     63             shouldThrow();
     64         } catch (IllegalArgumentException success) {}
     65     }
     66 
     67     /**
     68      * get returns the last value set or assigned
     69      */
     70     public void testGetSet() {
     71         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
     72         a = updaterFor("x");
     73         x = 1;
     74         assertEquals(1, a.get(this));
     75         a.set(this, 2);
     76         assertEquals(2, a.get(this));
     77         a.set(this, -3);
     78         assertEquals(-3, a.get(this));
     79     }
     80 
     81     /**
     82      * get returns the last value lazySet by same thread
     83      */
     84     public void testGetLazySet() {
     85         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
     86         a = updaterFor("x");
     87         x = 1;
     88         assertEquals(1, a.get(this));
     89         a.lazySet(this, 2);
     90         assertEquals(2, a.get(this));
     91         a.lazySet(this, -3);
     92         assertEquals(-3, a.get(this));
     93     }
     94 
     95     /**
     96      * compareAndSet succeeds in changing value if equal to expected else fails
     97      */
     98     public void testCompareAndSet() {
     99         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    100         a = updaterFor("x");
    101         x = 1;
    102         assertTrue(a.compareAndSet(this, 1, 2));
    103         assertTrue(a.compareAndSet(this, 2, -4));
    104         assertEquals(-4, a.get(this));
    105         assertFalse(a.compareAndSet(this, -5, 7));
    106         assertEquals(-4, a.get(this));
    107         assertTrue(a.compareAndSet(this, -4, 7));
    108         assertEquals(7, a.get(this));
    109     }
    110 
    111     /**
    112      * compareAndSet in one thread enables another waiting for value
    113      * to succeed
    114      */
    115     public void testCompareAndSetInMultipleThreads() throws Exception {
    116         x = 1;
    117         final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    118         a = updaterFor("x");
    119 
    120         Thread t = new Thread(new CheckedRunnable() {
    121             public void realRun() {
    122                 while (!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3))
    123                     Thread.yield();
    124             }});
    125 
    126         t.start();
    127         assertTrue(a.compareAndSet(this, 1, 2));
    128         t.join(LONG_DELAY_MS);
    129         assertFalse(t.isAlive());
    130         assertEquals(3, a.get(this));
    131     }
    132 
    133     /**
    134      * repeated weakCompareAndSet succeeds in changing value when equal
    135      * to expected
    136      */
    137     public void testWeakCompareAndSet() {
    138         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    139         a = updaterFor("x");
    140         x = 1;
    141         do {} while (!a.weakCompareAndSet(this, 1, 2));
    142         do {} while (!a.weakCompareAndSet(this, 2, -4));
    143         assertEquals(-4, a.get(this));
    144         do {} while (!a.weakCompareAndSet(this, -4, 7));
    145         assertEquals(7, a.get(this));
    146     }
    147 
    148     /**
    149      * getAndSet returns previous value and sets to given value
    150      */
    151     public void testGetAndSet() {
    152         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    153         a = updaterFor("x");
    154         x = 1;
    155         assertEquals(1, a.getAndSet(this, 0));
    156         assertEquals(0, a.getAndSet(this, -10));
    157         assertEquals(-10, a.getAndSet(this, 1));
    158     }
    159 
    160     /**
    161      * getAndAdd returns previous value and adds given value
    162      */
    163     public void testGetAndAdd() {
    164         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    165         a = updaterFor("x");
    166         x = 1;
    167         assertEquals(1, a.getAndAdd(this, 2));
    168         assertEquals(3, a.get(this));
    169         assertEquals(3, a.getAndAdd(this, -4));
    170         assertEquals(-1, a.get(this));
    171     }
    172 
    173     /**
    174      * getAndDecrement returns previous value and decrements
    175      */
    176     public void testGetAndDecrement() {
    177         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    178         a = updaterFor("x");
    179         x = 1;
    180         assertEquals(1, a.getAndDecrement(this));
    181         assertEquals(0, a.getAndDecrement(this));
    182         assertEquals(-1, a.getAndDecrement(this));
    183     }
    184 
    185     /**
    186      * getAndIncrement returns previous value and increments
    187      */
    188     public void testGetAndIncrement() {
    189         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    190         a = updaterFor("x");
    191         x = 1;
    192         assertEquals(1, a.getAndIncrement(this));
    193         assertEquals(2, a.get(this));
    194         a.set(this, -2);
    195         assertEquals(-2, a.getAndIncrement(this));
    196         assertEquals(-1, a.getAndIncrement(this));
    197         assertEquals(0, a.getAndIncrement(this));
    198         assertEquals(1, a.get(this));
    199     }
    200 
    201     /**
    202      * addAndGet adds given value to current, and returns current value
    203      */
    204     public void testAddAndGet() {
    205         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    206         a = updaterFor("x");
    207         x = 1;
    208         assertEquals(3, a.addAndGet(this, 2));
    209         assertEquals(3, a.get(this));
    210         assertEquals(-1, a.addAndGet(this, -4));
    211         assertEquals(-1, a.get(this));
    212     }
    213 
    214     /**
    215      * decrementAndGet decrements and returns current value
    216      */
    217     public void testDecrementAndGet() {
    218         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    219         a = updaterFor("x");
    220         x = 1;
    221         assertEquals(0, a.decrementAndGet(this));
    222         assertEquals(-1, a.decrementAndGet(this));
    223         assertEquals(-2, a.decrementAndGet(this));
    224         assertEquals(-2, a.get(this));
    225     }
    226 
    227     /**
    228      * incrementAndGet increments and returns current value
    229      */
    230     public void testIncrementAndGet() {
    231         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
    232         a = updaterFor("x");
    233         x = 1;
    234         assertEquals(2, a.incrementAndGet(this));
    235         assertEquals(2, a.get(this));
    236         a.set(this, -2);
    237         assertEquals(-1, a.incrementAndGet(this));
    238         assertEquals(0, a.incrementAndGet(this));
    239         assertEquals(1, a.incrementAndGet(this));
    240         assertEquals(1, a.get(this));
    241     }
    242 
    243 }
    244