test/jdk/java/util/concurrent/tck/AtomicIntegerArrayTest.java
changeset 47216 71c04702a3d5
parent 46146 b3e220a04d3f
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     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.Arrays;
       
    37 import java.util.concurrent.atomic.AtomicIntegerArray;
       
    38 
       
    39 import junit.framework.Test;
       
    40 import junit.framework.TestSuite;
       
    41 
       
    42 public class AtomicIntegerArrayTest extends JSR166TestCase {
       
    43 
       
    44     public static void main(String[] args) {
       
    45         main(suite(), args);
       
    46     }
       
    47     public static Test suite() {
       
    48         return new TestSuite(AtomicIntegerArrayTest.class);
       
    49     }
       
    50 
       
    51     /**
       
    52      * constructor creates array of given size with all elements zero
       
    53      */
       
    54     public void testConstructor() {
       
    55         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
    56         for (int i = 0; i < SIZE; i++)
       
    57             assertEquals(0, aa.get(i));
       
    58     }
       
    59 
       
    60     /**
       
    61      * constructor with null array throws NPE
       
    62      */
       
    63     public void testConstructor2NPE() {
       
    64         try {
       
    65             int[] a = null;
       
    66             new AtomicIntegerArray(a);
       
    67             shouldThrow();
       
    68         } catch (NullPointerException success) {}
       
    69     }
       
    70 
       
    71     /**
       
    72      * constructor with array is of same size and has all elements
       
    73      */
       
    74     public void testConstructor2() {
       
    75         int[] a = { 17, 3, -42, 99, -7 };
       
    76         AtomicIntegerArray aa = new AtomicIntegerArray(a);
       
    77         assertEquals(a.length, aa.length());
       
    78         for (int i = 0; i < a.length; i++)
       
    79             assertEquals(a[i], aa.get(i));
       
    80     }
       
    81 
       
    82     /**
       
    83      * get and set for out of bound indices throw IndexOutOfBoundsException
       
    84      */
       
    85     public void testIndexing() {
       
    86         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
    87         for (int index : new int[] { -1, SIZE }) {
       
    88             try {
       
    89                 aa.get(index);
       
    90                 shouldThrow();
       
    91             } catch (IndexOutOfBoundsException success) {}
       
    92             try {
       
    93                 aa.set(index, 1);
       
    94                 shouldThrow();
       
    95             } catch (IndexOutOfBoundsException success) {}
       
    96             try {
       
    97                 aa.lazySet(index, 1);
       
    98                 shouldThrow();
       
    99             } catch (IndexOutOfBoundsException success) {}
       
   100             try {
       
   101                 aa.compareAndSet(index, 1, 2);
       
   102                 shouldThrow();
       
   103             } catch (IndexOutOfBoundsException success) {}
       
   104             try {
       
   105                 aa.weakCompareAndSet(index, 1, 2);
       
   106                 shouldThrow();
       
   107             } catch (IndexOutOfBoundsException success) {}
       
   108             try {
       
   109                 aa.getAndAdd(index, 1);
       
   110                 shouldThrow();
       
   111             } catch (IndexOutOfBoundsException success) {}
       
   112             try {
       
   113                 aa.addAndGet(index, 1);
       
   114                 shouldThrow();
       
   115             } catch (IndexOutOfBoundsException success) {}
       
   116         }
       
   117     }
       
   118 
       
   119     /**
       
   120      * get returns the last value set at index
       
   121      */
       
   122     public void testGetSet() {
       
   123         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   124         for (int i = 0; i < SIZE; i++) {
       
   125             aa.set(i, 1);
       
   126             assertEquals(1, aa.get(i));
       
   127             aa.set(i, 2);
       
   128             assertEquals(2, aa.get(i));
       
   129             aa.set(i, -3);
       
   130             assertEquals(-3, aa.get(i));
       
   131         }
       
   132     }
       
   133 
       
   134     /**
       
   135      * get returns the last value lazySet at index by same thread
       
   136      */
       
   137     public void testGetLazySet() {
       
   138         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   139         for (int i = 0; i < SIZE; i++) {
       
   140             aa.lazySet(i, 1);
       
   141             assertEquals(1, aa.get(i));
       
   142             aa.lazySet(i, 2);
       
   143             assertEquals(2, aa.get(i));
       
   144             aa.lazySet(i, -3);
       
   145             assertEquals(-3, aa.get(i));
       
   146         }
       
   147     }
       
   148 
       
   149     /**
       
   150      * compareAndSet succeeds in changing value if equal to expected else fails
       
   151      */
       
   152     public void testCompareAndSet() {
       
   153         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   154         for (int i = 0; i < SIZE; i++) {
       
   155             aa.set(i, 1);
       
   156             assertTrue(aa.compareAndSet(i, 1, 2));
       
   157             assertTrue(aa.compareAndSet(i, 2, -4));
       
   158             assertEquals(-4, aa.get(i));
       
   159             assertFalse(aa.compareAndSet(i, -5, 7));
       
   160             assertEquals(-4, aa.get(i));
       
   161             assertTrue(aa.compareAndSet(i, -4, 7));
       
   162             assertEquals(7, aa.get(i));
       
   163         }
       
   164     }
       
   165 
       
   166     /**
       
   167      * compareAndSet in one thread enables another waiting for value
       
   168      * to succeed
       
   169      */
       
   170     public void testCompareAndSetInMultipleThreads() throws Exception {
       
   171         final AtomicIntegerArray a = new AtomicIntegerArray(1);
       
   172         a.set(0, 1);
       
   173         Thread t = new Thread(new CheckedRunnable() {
       
   174             public void realRun() {
       
   175                 while (!a.compareAndSet(0, 2, 3))
       
   176                     Thread.yield();
       
   177             }});
       
   178 
       
   179         t.start();
       
   180         assertTrue(a.compareAndSet(0, 1, 2));
       
   181         t.join(LONG_DELAY_MS);
       
   182         assertFalse(t.isAlive());
       
   183         assertEquals(3, a.get(0));
       
   184     }
       
   185 
       
   186     /**
       
   187      * repeated weakCompareAndSet succeeds in changing value when equal
       
   188      * to expected
       
   189      */
       
   190     public void testWeakCompareAndSet() {
       
   191         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   192         for (int i = 0; i < SIZE; i++) {
       
   193             aa.set(i, 1);
       
   194             do {} while (!aa.weakCompareAndSet(i, 1, 2));
       
   195             do {} while (!aa.weakCompareAndSet(i, 2, -4));
       
   196             assertEquals(-4, aa.get(i));
       
   197             do {} while (!aa.weakCompareAndSet(i, -4, 7));
       
   198             assertEquals(7, aa.get(i));
       
   199         }
       
   200     }
       
   201 
       
   202     /**
       
   203      * getAndSet returns previous value and sets to given value at given index
       
   204      */
       
   205     public void testGetAndSet() {
       
   206         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   207         for (int i = 0; i < SIZE; i++) {
       
   208             aa.set(i, 1);
       
   209             assertEquals(1, aa.getAndSet(i, 0));
       
   210             assertEquals(0, aa.getAndSet(i, -10));
       
   211             assertEquals(-10, aa.getAndSet(i, 1));
       
   212         }
       
   213     }
       
   214 
       
   215     /**
       
   216      * getAndAdd returns previous value and adds given value
       
   217      */
       
   218     public void testGetAndAdd() {
       
   219         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   220         for (int i = 0; i < SIZE; i++) {
       
   221             aa.set(i, 1);
       
   222             assertEquals(1, aa.getAndAdd(i, 2));
       
   223             assertEquals(3, aa.get(i));
       
   224             assertEquals(3, aa.getAndAdd(i, -4));
       
   225             assertEquals(-1, aa.get(i));
       
   226         }
       
   227     }
       
   228 
       
   229     /**
       
   230      * getAndDecrement returns previous value and decrements
       
   231      */
       
   232     public void testGetAndDecrement() {
       
   233         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   234         for (int i = 0; i < SIZE; i++) {
       
   235             aa.set(i, 1);
       
   236             assertEquals(1, aa.getAndDecrement(i));
       
   237             assertEquals(0, aa.getAndDecrement(i));
       
   238             assertEquals(-1, aa.getAndDecrement(i));
       
   239         }
       
   240     }
       
   241 
       
   242     /**
       
   243      * getAndIncrement returns previous value and increments
       
   244      */
       
   245     public void testGetAndIncrement() {
       
   246         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   247         for (int i = 0; i < SIZE; i++) {
       
   248             aa.set(i, 1);
       
   249             assertEquals(1, aa.getAndIncrement(i));
       
   250             assertEquals(2, aa.get(i));
       
   251             aa.set(i, -2);
       
   252             assertEquals(-2, aa.getAndIncrement(i));
       
   253             assertEquals(-1, aa.getAndIncrement(i));
       
   254             assertEquals(0, aa.getAndIncrement(i));
       
   255             assertEquals(1, aa.get(i));
       
   256         }
       
   257     }
       
   258 
       
   259     /**
       
   260      * addAndGet adds given value to current, and returns current value
       
   261      */
       
   262     public void testAddAndGet() {
       
   263         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   264         for (int i = 0; i < SIZE; i++) {
       
   265             aa.set(i, 1);
       
   266             assertEquals(3, aa.addAndGet(i, 2));
       
   267             assertEquals(3, aa.get(i));
       
   268             assertEquals(-1, aa.addAndGet(i, -4));
       
   269             assertEquals(-1, aa.get(i));
       
   270         }
       
   271     }
       
   272 
       
   273     /**
       
   274      * decrementAndGet decrements and returns current value
       
   275      */
       
   276     public void testDecrementAndGet() {
       
   277         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   278         for (int i = 0; i < SIZE; i++) {
       
   279             aa.set(i, 1);
       
   280             assertEquals(0, aa.decrementAndGet(i));
       
   281             assertEquals(-1, aa.decrementAndGet(i));
       
   282             assertEquals(-2, aa.decrementAndGet(i));
       
   283             assertEquals(-2, aa.get(i));
       
   284         }
       
   285     }
       
   286 
       
   287     /**
       
   288      * incrementAndGet increments and returns current value
       
   289      */
       
   290     public void testIncrementAndGet() {
       
   291         AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   292         for (int i = 0; i < SIZE; i++) {
       
   293             aa.set(i, 1);
       
   294             assertEquals(2, aa.incrementAndGet(i));
       
   295             assertEquals(2, aa.get(i));
       
   296             aa.set(i, -2);
       
   297             assertEquals(-1, aa.incrementAndGet(i));
       
   298             assertEquals(0, aa.incrementAndGet(i));
       
   299             assertEquals(1, aa.incrementAndGet(i));
       
   300             assertEquals(1, aa.get(i));
       
   301         }
       
   302     }
       
   303 
       
   304     class Counter extends CheckedRunnable {
       
   305         final AtomicIntegerArray aa;
       
   306         int decs;
       
   307         Counter(AtomicIntegerArray a) { aa = a; }
       
   308         public void realRun() {
       
   309             for (;;) {
       
   310                 boolean done = true;
       
   311                 for (int i = 0; i < aa.length(); i++) {
       
   312                     int v = aa.get(i);
       
   313                     assertTrue(v >= 0);
       
   314                     if (v != 0) {
       
   315                         done = false;
       
   316                         if (aa.compareAndSet(i, v, v - 1))
       
   317                             decs++;
       
   318                     }
       
   319                 }
       
   320                 if (done)
       
   321                     break;
       
   322             }
       
   323         }
       
   324     }
       
   325 
       
   326     /**
       
   327      * Multiple threads using same array of counters successfully
       
   328      * update a number of times equal to total count
       
   329      */
       
   330     public void testCountingInMultipleThreads() throws InterruptedException {
       
   331         final AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
       
   332         int countdown = 10000;
       
   333         for (int i = 0; i < SIZE; i++)
       
   334             aa.set(i, countdown);
       
   335         Counter c1 = new Counter(aa);
       
   336         Counter c2 = new Counter(aa);
       
   337         Thread t1 = newStartedThread(c1);
       
   338         Thread t2 = newStartedThread(c2);
       
   339         t1.join();
       
   340         t2.join();
       
   341         assertEquals(c1.decs + c2.decs, SIZE * countdown);
       
   342     }
       
   343 
       
   344     /**
       
   345      * a deserialized/reserialized array holds same values in same order
       
   346      */
       
   347     public void testSerialization() throws Exception {
       
   348         AtomicIntegerArray x = new AtomicIntegerArray(SIZE);
       
   349         for (int i = 0; i < SIZE; i++)
       
   350             x.set(i, -i);
       
   351         AtomicIntegerArray y = serialClone(x);
       
   352         assertNotSame(x, y);
       
   353         assertEquals(x.length(), y.length());
       
   354         for (int i = 0; i < SIZE; i++) {
       
   355             assertEquals(x.get(i), y.get(i));
       
   356         }
       
   357     }
       
   358 
       
   359     /**
       
   360      * toString returns current value.
       
   361      */
       
   362     public void testToString() {
       
   363         int[] a = { 17, 3, -42, 99, -7 };
       
   364         AtomicIntegerArray aa = new AtomicIntegerArray(a);
       
   365         assertEquals(Arrays.toString(a), aa.toString());
       
   366     }
       
   367 
       
   368 }