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