OpenJDK / lambda / lambda / jdk
changeset 8123:4e09b3aa8149
add Tests for AtomicXXX.accumulateAndGet()/getAndAccumulate()
author | Tristan Yan <tristan.yan@oracle.com> |
---|---|
date | Fri, 05 Apr 2013 12:39:26 +0800 |
parents | e473df6aaa89 |
children | e6393d7abb72 |
files | test/java/util/concurrent/AtomicInteger/LambdaTest.java test/java/util/concurrent/AtomicInteger/UpdateAndGetTest.java test/java/util/concurrent/AtomicIntegerFieldUpdater/LambdaTest.java test/java/util/concurrent/AtomicIntegerFieldUpdater/UpdateAndGetTest.java test/java/util/concurrent/AtomicLong/LambdaTest.java test/java/util/concurrent/AtomicLong/UpdateAndGetTest.java test/java/util/concurrent/AtomicLongFieldUpdater/LambdaTest.java test/java/util/concurrent/AtomicLongFieldUpdater/UpdateAndGetTest.java test/java/util/concurrent/AtomicReference/LambdaTest.java test/java/util/concurrent/AtomicReference/UpdateAndGetTest.java test/java/util/concurrent/AtomicReferenceFieldUpdater/LambdaTest.java test/java/util/concurrent/AtomicReferenceFieldUpdater/UpdateAndGetTest.java |
diffstat | 12 files changed, 1251 insertions(+), 940 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/concurrent/AtomicInteger/LambdaTest.java Fri Apr 05 12:39:26 2013 +0800 @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary test for AtomicInteger.updateAndGet()/getAndUpdate() and + * AtomicInteger.accumulateAndGet()/getAndAccumulate(); + * @(#) LambdaTest.java + * @library ../../ + * @author Tristan Yan + * @bug 8001666 + * @run testng LambdaTest + */ + +import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; +import java.util.concurrent.atomic.AtomicInteger; +import static org.testng.Assert.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class LambdaTest { + private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate}; + + private static Random rand = new Random(System.currentTimeMillis()); + + private final static int MAX_VALUE = 1 << 24; + + private final static int MIN_VALUE = -1 << 24; + + private final static int OP_TIMES = 1 << 10; + + private final static int THREAD_NUM = 1 << 4; + + @DataProvider + public Object[][] booleanProvider(){ + Object[][] providersParam = new Object[Type.values().length][]; + Object[] a = Type.values(); + for(int i = 0; i < a.length; i++) + providersParam[i] = new Object[]{a[i]}; + return providersParam; + } + + @Test(dataProvider = "booleanProvider") + @SuppressWarnings({"rawtypes", "unchecked"}) + public void test(final Type type) throws InterruptedException, + ExecutionException { + int initValue = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); + final AtomicInteger ai = new AtomicInteger(initValue); + final int randPlus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); + final int randMinus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); + switch(type) { + case updateAndGet: + assertEquals(ai.updateAndGet(LambdaUtilities.addIntUnaryOperator(randPlus)) + , initValue + randPlus); + assertEquals(ai.updateAndGet(LambdaUtilities.subIntUnaryOperator(randMinus)) + , initValue + randPlus - randMinus); + break; + case getAndUpdate: + assertEquals(ai.getAndUpdate(LambdaUtilities.addIntUnaryOperator(randPlus)) + , initValue); + assertEquals(ai.getAndUpdate(LambdaUtilities.subIntUnaryOperator(randMinus)) + , initValue + randPlus); + break; + case accumulateAndGet: + assertEquals(ai.accumulateAndGet(randPlus,LambdaUtilities.addIntBinaryOperator()) + , initValue + randPlus); + assertEquals(ai.accumulateAndGet(randMinus,LambdaUtilities.subIntBinaryOperator()) + , initValue + randPlus - randMinus); + break; + case getAndAccumulate: + assertEquals(ai.getAndAccumulate(randPlus,LambdaUtilities.addIntBinaryOperator()) + , initValue); + assertEquals(ai.getAndAccumulate(randMinus,LambdaUtilities.subIntBinaryOperator()) + , initValue + randPlus); + break; + } + assertEquals(ai.get(), initValue + randPlus - randMinus); + + ai.set(initValue); + Callable<Integer> ac = new Callable<Integer>(){ + @Override + public Integer call() throws Exception { + int plusTimes1 = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + if(plus) plusTimes1++; + switch(type) { + case updateAndGet: + ai.updateAndGet(plus ? + LambdaUtilities.addIntUnaryOperator(randPlus) : + LambdaUtilities.subIntUnaryOperator(randMinus)); + break; + case getAndUpdate: + ai.getAndUpdate(plus ? + LambdaUtilities.addIntUnaryOperator(randPlus) : + LambdaUtilities.subIntUnaryOperator(randMinus)); + break; + case accumulateAndGet: + ai.accumulateAndGet(plus ? randPlus : randMinus, + plus ? LambdaUtilities.addIntBinaryOperator() : + LambdaUtilities.subIntBinaryOperator()); + break; + case getAndAccumulate: + ai.getAndAccumulate(plus ? randPlus : randMinus, + plus ? LambdaUtilities.addIntBinaryOperator() : + LambdaUtilities.subIntBinaryOperator()); + } + } + return plusTimes1; + } + + }; + FutureTask[] futures = new FutureTask[THREAD_NUM -1]; + for(int i = 0; i < THREAD_NUM -1; i++) { + futures[i] = new FutureTask<Integer>(ac); + new Thread(futures[i]).start(); + } + + int plusTimes = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + if(plus) plusTimes++; + switch(type) { + case updateAndGet: + ai.updateAndGet(plus ? + LambdaUtilities.addIntUnaryOperator(randPlus) : + LambdaUtilities.subIntUnaryOperator(randMinus)); + break; + case getAndUpdate: + ai.getAndUpdate(plus ? + LambdaUtilities.addIntUnaryOperator(randPlus) : + LambdaUtilities.subIntUnaryOperator(randMinus)); + break; + case accumulateAndGet: + ai.accumulateAndGet(plus ? randPlus : randMinus, + plus ? LambdaUtilities.addIntBinaryOperator() : + LambdaUtilities.subIntBinaryOperator()); + break; + case getAndAccumulate: + ai.getAndAccumulate(plus ? randPlus : randMinus, + plus ? LambdaUtilities.addIntBinaryOperator() : + LambdaUtilities.subIntBinaryOperator()); + } + } + for(int i = 0; i < THREAD_NUM -1; i++) { + plusTimes += ((FutureTask<Integer>)futures[i]).get(); + } + int expected = initValue + plusTimes * randPlus - + (THREAD_NUM * OP_TIMES - plusTimes) * randMinus; + assertEquals(expected, ai.get()); + } +}
--- a/test/java/util/concurrent/AtomicInteger/UpdateAndGetTest.java Thu Apr 04 22:28:40 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @summary test AtomicInteger.updateAndGet()/getAndUpdate(); - * @(#) UpdateAndGetTest.java - * @library ../../ - * @author Tristan Yan - * @bug 8001666 - * @run testng UpdateAndGetTest - */ - -import java.util.Random; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; -import java.util.concurrent.atomic.AtomicInteger; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -public class UpdateAndGetTest { - private static Random rand = new Random(System.currentTimeMillis()); - - private final static int MAX_VALUE = 1 << 24; - - private final static int MIN_VALUE = -1 << 24; - - private final static int OP_TIMES = 1 << 10; - - private final static int THREAD_NUM = 1 << 4; - - @DataProvider - public Object[][] booleanProvider(){ - return new Object[][]{ - {Boolean.TRUE}, - {Boolean.FALSE} - }; - } - - @Test(dataProvider = "booleanProvider") - @SuppressWarnings({"rawtypes", "unchecked"}) - public void testUpdateAndGet(final boolean updateAndGet) throws InterruptedException, - ExecutionException { - int initValue = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); - final AtomicInteger ai = new AtomicInteger(initValue); - final int randPlus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); - final int randMinus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); - if(updateAndGet) { - assertEquals(ai.updateAndGet(LambdaUtilities.addIntUnaryOperator(randPlus)) - , initValue + randPlus); - assertEquals(ai.updateAndGet(LambdaUtilities.subIntUnaryOperator(randMinus)) - , initValue + randPlus - randMinus); - } else { - assertEquals(ai.getAndUpdate(LambdaUtilities.addIntUnaryOperator(randPlus)) - , initValue); - assertEquals(ai.getAndUpdate(LambdaUtilities.subIntUnaryOperator(randMinus)) - , initValue + randPlus); - } - assertEquals(ai.get(), initValue + randPlus - randMinus); - - ai.set(initValue); - Callable<Integer> ac = new Callable<Integer>(){ - @Override - public Integer call() throws Exception { - int plusTimes1 = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(plus) plusTimes1++; - if(updateAndGet) - ai.updateAndGet(plus ? - LambdaUtilities.addIntUnaryOperator(randPlus) : - LambdaUtilities.subIntUnaryOperator(randMinus)); - else - ai.getAndUpdate(plus ? - LambdaUtilities.addIntUnaryOperator(randPlus) : - LambdaUtilities.subIntUnaryOperator(randMinus)); - } - return plusTimes1; - } - - }; - FutureTask[] futures = new FutureTask[THREAD_NUM -1]; - for(int i = 0; i < THREAD_NUM -1; i++) { - futures[i] = new FutureTask<Integer>(ac); - new Thread(futures[i]).start(); - } - - int plusTimes = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(plus) plusTimes++; - if(updateAndGet) - ai.updateAndGet(plus ? - LambdaUtilities.addIntUnaryOperator(randPlus) : - LambdaUtilities.subIntUnaryOperator(randMinus)); - else - ai.getAndUpdate(plus ? - LambdaUtilities.addIntUnaryOperator(randPlus) : - LambdaUtilities.subIntUnaryOperator(randMinus)); - } - for(int i = 0; i < THREAD_NUM -1; i++) { - plusTimes += ((FutureTask<Integer>)futures[i]).get(); - } - int expected = initValue + plusTimes * randPlus - - (THREAD_NUM * OP_TIMES - plusTimes) * randMinus; - assertEquals(expected, ai.get()); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/concurrent/AtomicIntegerFieldUpdater/LambdaTest.java Fri Apr 05 12:39:26 2013 +0800 @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/** + * @test + * @summary test for AtomicIntegerUpdateField.updateAndGet()/getAndUpdate() and + * AtomicIntegerUpdateField.accumulateAndGet()/getAndAccumulate(); + * @(#) LambdaTest.java + * @library ../../ + * @author Tristan Yan + * @run testng LambdaTest + * @bug 8001666 + */ + +import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import static org.testng.Assert.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class LambdaTest { + private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate}; + + private static Random rand = new Random(System.currentTimeMillis()); + + private final static int MAX_VALUE = 1 << 24; + + private final static int MIN_VALUE = -1 << 24; + + private final static int OP_TIMES = 1 << 10; + + private final static int THREAD_NUM = 1 << 4; + + @DataProvider + public Object[][] booleanProvider(){ + Object[][] providersParam = new Object[Type.values().length][]; + Object[] a = Type.values(); + for(int i = 0; i < a.length; i++) + providersParam[i] = new Object[]{a[i]}; + return providersParam; + } + + @Test(dataProvider = "booleanProvider") + @SuppressWarnings({"rawtypes", "unchecked"}) + public void test(final Type type) throws InterruptedException, + ExecutionException { + final Updater u = new Updater(); + final AtomicIntegerFieldUpdater<Updater> accAIFU = AtomicIntegerFieldUpdater.<Updater>newUpdater((Class<Updater>)(Class<?>)u.getClass(), "accumulation"); + final int randPlus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); + final int randMinus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); + switch(type) { + case updateAndGet: + assertEquals(accAIFU.updateAndGet(u, + LambdaUtilities.addIntUnaryOperator(randPlus)), randPlus); + assertEquals(accAIFU.updateAndGet(u, + LambdaUtilities.subIntUnaryOperator(randMinus)), randPlus - randMinus); + break; + case getAndUpdate: + assertEquals(accAIFU.getAndUpdate(u, + LambdaUtilities.addIntUnaryOperator(randPlus)), 0); + assertEquals(accAIFU.getAndUpdate(u, + LambdaUtilities.subIntUnaryOperator(randMinus)), randPlus); + break; + case accumulateAndGet: + assertEquals(accAIFU.accumulateAndGet(u, randPlus, + LambdaUtilities.addIntBinaryOperator()), randPlus); + assertEquals(accAIFU.accumulateAndGet(u, randMinus, + LambdaUtilities.subIntBinaryOperator()), randPlus - randMinus); + break; + case getAndAccumulate: + assertEquals(accAIFU.getAndAccumulate(u, randPlus, + LambdaUtilities.addIntBinaryOperator()), 0); + assertEquals(accAIFU.getAndAccumulate(u, randMinus, + LambdaUtilities.subIntBinaryOperator()), randPlus); + break; + } + assertEquals(u.accumulation, randPlus - randMinus); + + u.accumulation = 0; + + Callable<Integer> ac = new Callable<Integer>(){ + @Override + public Integer call() throws Exception { + int plusTimes = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + if(plus) plusTimes++; + switch(type) { + case updateAndGet: + accAIFU.updateAndGet(u, plus ? + LambdaUtilities.addIntUnaryOperator(randPlus) : + LambdaUtilities.subIntUnaryOperator(randMinus)); + break; + case getAndUpdate: + accAIFU.getAndUpdate(u, plus ? + LambdaUtilities.addIntUnaryOperator(randPlus) : + LambdaUtilities.subIntUnaryOperator(randMinus)); + break; + case accumulateAndGet: + accAIFU.accumulateAndGet(u, plus ? randPlus : randMinus, + plus ? LambdaUtilities.addIntBinaryOperator() : + LambdaUtilities.subIntBinaryOperator()); + break; + case getAndAccumulate: + accAIFU.getAndAccumulate(u, plus ? randPlus : randMinus, + plus ? LambdaUtilities.addIntBinaryOperator() : + LambdaUtilities.subIntBinaryOperator()); + break; + } + } + return plusTimes; + } + }; + + FutureTask[] futures = new FutureTask[THREAD_NUM -1]; + for(int i = 0; i < THREAD_NUM -1; i++) { + futures[i] = new FutureTask<Integer>(ac); + new Thread(futures[i]).start(); + } + int plusTimes = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + if(plus) plusTimes++; + switch(type) { + case updateAndGet: + accAIFU.updateAndGet(u, plus ? + LambdaUtilities.addIntUnaryOperator(randPlus) : + LambdaUtilities.subIntUnaryOperator(randMinus)); + break; + case getAndUpdate: + accAIFU.getAndUpdate(u, plus ? + LambdaUtilities.addIntUnaryOperator(randPlus) : + LambdaUtilities.subIntUnaryOperator(randMinus)); + break; + case accumulateAndGet: + accAIFU.accumulateAndGet(u, plus ? randPlus : randMinus, + plus ? LambdaUtilities.addIntBinaryOperator() : + LambdaUtilities.subIntBinaryOperator()); + break; + case getAndAccumulate: + accAIFU.getAndAccumulate(u, plus ? randPlus : randMinus, + plus ? LambdaUtilities.addIntBinaryOperator() : + LambdaUtilities.subIntBinaryOperator()); + break; + } + } + for(int i = 0; i < THREAD_NUM -1; i++) { + plusTimes += ((FutureTask<Integer>)futures[i]).get(); + } + int expected = plusTimes * randPlus - + (THREAD_NUM * OP_TIMES - plusTimes) * randMinus; + assertEquals(expected, u.accumulation); + } + + static class Updater{ + public volatile int accumulation; + } +} \ No newline at end of file
--- a/test/java/util/concurrent/AtomicIntegerFieldUpdater/UpdateAndGetTest.java Thu Apr 04 22:28:40 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -/** - * @test - * @summary test AtomicIntegerUpdateField.updateAndGet()/getAndUpdate(); - * @(#) UpdateAndGetTest.java - * @library ../../ - * @author Tristan Yan - * @run testng UpdateAndGetTest - * @bug 8001666 - */ - -import java.util.Random; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -public class UpdateAndGetTest { - private static Random rand = new Random(System.currentTimeMillis()); - - private final static int MAX_VALUE = 1 << 24; - - private final static int MIN_VALUE = -1 << 24; - - private final static int OP_TIMES = 1 << 10; - - private final static int THREAD_NUM = 1 << 4; - - @DataProvider - public Object[][] booleanProvider(){ - return new Object[][]{ - {Boolean.TRUE}, - {Boolean.FALSE} - }; - } - - @Test(dataProvider = "booleanProvider") - @SuppressWarnings({"rawtypes", "unchecked"}) - public void testUpdateAndGet(final boolean updateAndGet) throws InterruptedException, - ExecutionException { - final Updater u = new Updater(); - final AtomicIntegerFieldUpdater<Updater> accAIFU = AtomicIntegerFieldUpdater.<Updater>newUpdater((Class<Updater>)(Class<?>)u.getClass(), "accumulation"); - final int randPlus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); - final int randMinus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE); - if(updateAndGet) { - assertEquals(accAIFU.updateAndGet(u, LambdaUtilities.addIntUnaryOperator(randPlus)), randPlus); - assertEquals(accAIFU.updateAndGet(u, LambdaUtilities.subIntUnaryOperator(randMinus)), randPlus - randMinus); - } else { - assertEquals(accAIFU.getAndUpdate(u, LambdaUtilities.addIntUnaryOperator(randPlus)), 0); - assertEquals(accAIFU.getAndUpdate(u, LambdaUtilities.subIntUnaryOperator(randMinus)), randPlus); - } - assertEquals(u.accumulation, randPlus - randMinus); - - u.accumulation = 0; - - Callable<Integer> ac = new Callable<Integer>(){ - @Override - public Integer call() throws Exception { - int plusTimes = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(plus) plusTimes++; - if(updateAndGet) - accAIFU.updateAndGet(u, plus ? - LambdaUtilities.addIntUnaryOperator(randPlus) : - LambdaUtilities.subIntUnaryOperator(randMinus)); - else - accAIFU.getAndUpdate(u, plus ? - LambdaUtilities.addIntUnaryOperator(randPlus) : - LambdaUtilities.subIntUnaryOperator(randMinus)); - } - return plusTimes; - } - }; - - FutureTask[] futures = new FutureTask[THREAD_NUM -1]; - for(int i = 0; i < THREAD_NUM -1; i++) { - futures[i] = new FutureTask<Integer>(ac); - new Thread(futures[i]).start(); - } - int plusTimes = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(plus) plusTimes++; - if(updateAndGet) - accAIFU.updateAndGet(u, plus ? - LambdaUtilities.addIntUnaryOperator(randPlus) : - LambdaUtilities.subIntUnaryOperator(randMinus)); - else - accAIFU.getAndUpdate(u, plus ? - LambdaUtilities.addIntUnaryOperator(randPlus) : - LambdaUtilities.subIntUnaryOperator(randMinus)); - } - for(int i = 0; i < THREAD_NUM -1; i++) { - plusTimes += ((FutureTask<Integer>)futures[i]).get(); - } - int expected = plusTimes * randPlus - - (THREAD_NUM * OP_TIMES - plusTimes) * randMinus; - assertEquals(expected, u.accumulation); - } - - static class Updater{ - public volatile int accumulation; - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/concurrent/AtomicLong/LambdaTest.java Fri Apr 05 12:39:26 2013 +0800 @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary test AtomicLong.updateAndGet()/getAndUpdate() and + * AtomicLong.accumulateAndGet()/getAndAccumulate(); + * @(#) LambdaTest.java + * @library ../../ + * @author Tristan Yan + * @run testng LambdaTest + * @bug 8001666 + */ + +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicLong; +import static org.testng.Assert.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + + +public class LambdaTest { + private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate}; + + private static Random rand = new Random(System.currentTimeMillis()); + + private final static int MAX_VALUE = 1 << 24; + + private final static int MIN_VALUE = -1 << 24; + + private final static int OP_TIMES = 1 << 10; + + private final static int THREAD_NUM = 1 << 4; + + @DataProvider + public Object[][] booleanProvider(){ + Object[][] providersParam = new Object[Type.values().length][]; + Object[] a = Type.values(); + for(int i = 0; i < a.length; i++) + providersParam[i] = new Object[]{a[i]}; + return providersParam; + } + + @Test(dataProvider = "booleanProvider") + public void test(final Type type) throws InterruptedException, + ExecutionException { + long initValue = rand.nextLong(); + final AtomicLong al = new AtomicLong(initValue); + long tl1 = rand.nextLong(); + if(((byte)(tl1 >> 63) & (byte)(initValue >> 63)) == 0){ + if(initValue > 0) { + if(tl1 > Long.MAX_VALUE - initValue) + tl1 = - tl1; + } else { + if(tl1 < Long.MIN_VALUE - initValue) + tl1 = - tl1; + } + } + final long randPlus = tl1; + + long tl2 = rand.nextLong(); + if(((byte)(tl2 >> 63) & (byte)(initValue + randPlus >> 63)) == 1){ + if(initValue + randPlus > 0) { + if(-tl2 > Long.MAX_VALUE - (initValue + randPlus)) + tl2 = - tl2; + } else { + if(tl2 < Long.MIN_VALUE + (initValue + randPlus)) + tl2 = - tl2; + } + } + final long randMinus = tl2; + switch(type) { + case updateAndGet: + assertEquals(al.updateAndGet(LambdaUtilities.addLongUnaryOperator(randPlus)) + , initValue + randPlus); + assertEquals(al.updateAndGet(LambdaUtilities.subLongUnaryOperator(randMinus)) + , initValue + randPlus - randMinus); + break; + case getAndUpdate: + assertEquals(al.getAndUpdate(LambdaUtilities.addLongUnaryOperator(randPlus)) + , initValue); + assertEquals(al.getAndUpdate(LambdaUtilities.subLongUnaryOperator(randMinus)) + , initValue + randPlus); + break; + case accumulateAndGet: + assertEquals(al.accumulateAndGet(randPlus, LambdaUtilities.addLongBinaryOperator()) + , initValue + randPlus); + assertEquals(al.accumulateAndGet(randMinus, LambdaUtilities.subLongBinaryOperator()) + , initValue + randPlus - randMinus); + break; + case getAndAccumulate: + assertEquals(al.getAndAccumulate(randPlus, LambdaUtilities.addLongBinaryOperator()) + , initValue); + assertEquals(al.getAndAccumulate(randMinus, LambdaUtilities.subLongBinaryOperator()) + , initValue + randPlus); + break; + } + assertEquals(al.get() , initValue + randPlus - randMinus); + + final long randPlus1 = rand.nextBoolean() ? (long)rand.nextInt(MAX_VALUE) : -(long)rand.nextInt(MAX_VALUE); + final long randMinus1 = rand.nextBoolean() ? (long)rand.nextInt(MAX_VALUE) : -(long)rand.nextInt(MAX_VALUE); + al.set(initValue); + final int mainPLusTimes = 0; + int minusPLusTimes = 0; + + class UpdateThread extends Thread{ + OpTimes ops; + CountDownLatch latch; + UpdateThread(OpTimes ops, CountDownLatch latch){ + this.ops = ops; + this.latch = latch; + } + @Override + public void run() { + int plusTimes = 0; + int minusTimes = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + if(plus) { + if (randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1 + || randPlus1 < 0 && al.get() < Long.MIN_VALUE - randPlus1) + continue; + } + else { + if (randPlus1 > 0 && al.get() < Long.MIN_VALUE + randPlus1 + || randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1) + continue; + } + switch(type) { + case updateAndGet: + al.updateAndGet(plus ? + LambdaUtilities.addLongUnaryOperator(randPlus1) : + LambdaUtilities.subLongUnaryOperator(randMinus1)); + break; + case getAndUpdate: + al.getAndUpdate(plus ? + LambdaUtilities.addLongUnaryOperator(randPlus1) : + LambdaUtilities.subLongUnaryOperator(randMinus1)); + break; + case accumulateAndGet: + al.accumulateAndGet(plus ? randPlus1 : randMinus1, + plus ? LambdaUtilities.addLongBinaryOperator() : + LambdaUtilities.subLongBinaryOperator()); + break; + case getAndAccumulate: + al.getAndAccumulate(plus ? randPlus1 : randMinus1, + plus ? LambdaUtilities.addLongBinaryOperator() : + LambdaUtilities.subLongBinaryOperator()); + break; + } + if(plus) + plusTimes++; + else + minusTimes++; + } + ops.plus = plusTimes; + ops.minus = minusTimes; + latch.countDown(); + } + + }; + OpTimes[] opts = new OpTimes[THREAD_NUM -1]; + CountDownLatch latch = new CountDownLatch(THREAD_NUM -1); + for(int i = 0; i < THREAD_NUM -1; i++) { + opts[i] = new OpTimes(); + new UpdateThread(opts[i], latch).start(); + } + int plusTimes = 0; + int minusTimes = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + if(plus) { + if (randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1 + || randPlus1 < 0 && al.get() < Long.MIN_VALUE - randPlus1) + continue; + } + else { + if (randPlus1 > 0 && al.get() < Long.MIN_VALUE + randPlus1 + || randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1) + continue; + } + switch(type) { + case updateAndGet: + al.updateAndGet(plus ? + LambdaUtilities.addLongUnaryOperator(randPlus1) : + LambdaUtilities.subLongUnaryOperator(randMinus1)); + break; + case getAndUpdate: + al.getAndUpdate(plus ? + LambdaUtilities.addLongUnaryOperator(randPlus1) : + LambdaUtilities.subLongUnaryOperator(randMinus1)); + break; + case accumulateAndGet: + al.accumulateAndGet(plus ? randPlus1 : randMinus1, + plus ? LambdaUtilities.addLongBinaryOperator() : + LambdaUtilities.subLongBinaryOperator()); + break; + case getAndAccumulate: + al.getAndAccumulate(plus ? randPlus1 : randMinus1, + plus ? LambdaUtilities.addLongBinaryOperator() : + LambdaUtilities.subLongBinaryOperator()); + break; + } + if(plus) + plusTimes++; + else + minusTimes++; + } + latch.await(); + for(int i = 0; i < THREAD_NUM -1; i++) { + plusTimes += opts[i].plus; + minusTimes += opts[i].minus; + } + long expected = initValue + plusTimes * randPlus1 - + minusTimes * randMinus1; + assertEquals(expected, al.get()); + } +} +class OpTimes{ + public int plus; + + public int minus; +} \ No newline at end of file
--- a/test/java/util/concurrent/AtomicLong/UpdateAndGetTest.java Thu Apr 04 22:28:40 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @summary test AtomicLong.updateAndGet()/getAndUpdate(); - * @(#) UpdateAndGetTest.java - * @library ../../ - * @author Tristan Yan - * @run testng UpdateAndGetTest - * @bug 8001666 - */ - -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicLong; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -public class UpdateAndGetTest { - private static Random rand = new Random(System.currentTimeMillis()); - - private final static int MAX_VALUE = 1 << 24; - - private final static int MIN_VALUE = -1 << 24; - - private final static int OP_TIMES = 1 << 10; - - private final static int THREAD_NUM = 1 << 4; - - @DataProvider - public Object[][] booleanProvider(){ - return new Object[][]{ - {Boolean.TRUE}, - {Boolean.FALSE} - }; - } - - @Test(dataProvider = "booleanProvider") - public void testUpdateAndGet(final boolean updateAndGet) throws InterruptedException, - ExecutionException { - long initValue = rand.nextLong(); - final AtomicLong al = new AtomicLong(initValue); - long tl1 = rand.nextLong(); - if(((byte)(tl1 >> 63) & (byte)(initValue >> 63)) == 0){ - if(initValue > 0) { - if(tl1 > Long.MAX_VALUE - initValue) - tl1 = - tl1; - } else { - if(tl1 < Long.MIN_VALUE - initValue) - tl1 = - tl1; - } - } - final long randPlus = tl1; - - long tl2 = rand.nextLong(); - if(((byte)(tl2 >> 63) & (byte)(initValue + randPlus >> 63)) == 1){ - if(initValue + randPlus > 0) { - if(-tl2 > Long.MAX_VALUE - (initValue + randPlus)) - tl2 = - tl2; - } else { - if(tl2 < Long.MIN_VALUE + (initValue + randPlus)) - tl2 = - tl2; - } - } - final long randMinus = tl2; - if(updateAndGet) { - assertEquals(al.updateAndGet(LambdaUtilities.addLongUnaryOperator(randPlus)) - , initValue + randPlus); - assertEquals(al.updateAndGet(LambdaUtilities.subLongUnaryOperator(randMinus)) - , initValue + randPlus - randMinus); - } else { - assertEquals(al.getAndUpdate(LambdaUtilities.addLongUnaryOperator(randPlus)) - , initValue); - assertEquals(al.getAndUpdate(LambdaUtilities.subLongUnaryOperator(randMinus)) - , initValue + randPlus); - } - assertEquals(al.get() , initValue + randPlus - randMinus); - - final long randPlus1 = rand.nextBoolean() ? (long)rand.nextInt(MAX_VALUE) : -(long)rand.nextInt(MAX_VALUE); - final long randMinus1 = rand.nextBoolean() ? (long)rand.nextInt(MAX_VALUE) : -(long)rand.nextInt(MAX_VALUE); - al.set(initValue); - final int mainPLusTimes = 0; - int minusPLusTimes = 0; - - class UpdateThread extends Thread{ - OpTimes ops; - CountDownLatch latch; - UpdateThread(OpTimes ops, CountDownLatch latch){ - this.ops = ops; - this.latch = latch; - } - @Override - public void run() { - int plusTimes = 0; - int minusTimes = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(plus) { - if (randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1 - || randPlus1 < 0 && al.get() < Long.MIN_VALUE - randPlus1) - continue; - } - else { - if (randPlus1 > 0 && al.get() < Long.MIN_VALUE + randPlus1 - || randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1) - continue; - } - if(updateAndGet) - al.updateAndGet(plus ? - LambdaUtilities.addLongUnaryOperator(randPlus1) : - LambdaUtilities.subLongUnaryOperator(randMinus1)); - else - al.getAndUpdate(plus ? - LambdaUtilities.addLongUnaryOperator(randPlus1) : - LambdaUtilities.subLongUnaryOperator(randMinus1)); - if(plus) - plusTimes++; - else - minusTimes++; - } - ops.plus = plusTimes; - ops.minus = minusTimes; - latch.countDown(); - } - - }; - OpTimes[] opts = new OpTimes[THREAD_NUM -1]; - CountDownLatch latch = new CountDownLatch(THREAD_NUM -1); - for(int i = 0; i < THREAD_NUM -1; i++) { - opts[i] = new OpTimes(); - new UpdateThread(opts[i], latch).start(); - } - int plusTimes = 0; - int minusTimes = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(plus) { - if (randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1 - || randPlus1 < 0 && al.get() < Long.MIN_VALUE - randPlus1) - continue; - } - else { - if (randPlus1 > 0 && al.get() < Long.MIN_VALUE + randPlus1 - || randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1) - continue; - } - if(updateAndGet) - al.updateAndGet(plus ? - LambdaUtilities.addLongUnaryOperator(randPlus1) : - LambdaUtilities.subLongUnaryOperator(randMinus1)); - else - al.getAndUpdate(plus ? - LambdaUtilities.addLongUnaryOperator(randPlus1) : - LambdaUtilities.subLongUnaryOperator(randMinus1)); - if(plus) - plusTimes++; - else - minusTimes++; - } - latch.await(); - for(int i = 0; i < THREAD_NUM -1; i++) { - plusTimes += opts[i].plus; - minusTimes += opts[i].minus; - } - long expected = initValue + plusTimes * randPlus1 - - minusTimes * randMinus1; - assertEquals(expected, al.get()); - } -} - -class OpTimes{ - public int plus; - - public int minus; -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/concurrent/AtomicLongFieldUpdater/LambdaTest.java Fri Apr 05 12:39:26 2013 +0800 @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary test AtomicLongFieldUpdater.updateAndGet()/getAndUpdate() and + * AtomicLongFieldUpdater.accumulateAndGet()/getAndAccumulate(); + * @(#) LambdaTest.java + * @library ../../ + * @author Tristan Yan + * @run testng LambdaTest + * @bug 8001666 + */ + +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import static org.testng.Assert.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class LambdaTest { + private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate}; + + private static Random rand = new Random(System.currentTimeMillis()); + + private final static int OP_TIMES = 1 << 10; + + private final static int THREAD_NUM = 1 << 4; + + @DataProvider + public Object[][] booleanProvider(){ + Object[][] providersParam = new Object[Type.values().length][]; + Object[] a = Type.values(); + for(int i = 0; i < a.length; i++) + providersParam[i] = new Object[]{a[i]}; + return providersParam; + } + + @Test(dataProvider = "booleanProvider") + @SuppressWarnings({"rawtypes", "unchecked"}) + public void test(final Type type) throws InterruptedException, + ExecutionException { + long initValue = rand.nextLong(); + final Updater u = new Updater(); + u.accumulation = initValue; + final AtomicLongFieldUpdater<Updater> accAIFU + = AtomicLongFieldUpdater.<Updater>newUpdater((Class<Updater>)(Class<?>)u.getClass(), "accumulation"); + final long randPlus = rand.nextLong(); + final long randMinus = rand.nextLong(); + switch(type) { + case updateAndGet: + assertEquals(accAIFU.updateAndGet(u, + LambdaUtilities.addLongUnaryOperator(randPlus)), + initValue + randPlus); + assertEquals(accAIFU.updateAndGet(u, + LambdaUtilities.subLongUnaryOperator(randMinus)), + initValue + randPlus - randMinus); + break; + case getAndUpdate: + assertEquals(accAIFU.getAndUpdate(u, + LambdaUtilities.addLongUnaryOperator(randPlus)), + initValue); + assertEquals(accAIFU.getAndUpdate(u, + LambdaUtilities.subLongUnaryOperator(randMinus)), + initValue + randPlus); + break; + case accumulateAndGet: + assertEquals(accAIFU.accumulateAndGet(u, randPlus, + LambdaUtilities.addLongBinaryOperator()), + initValue + randPlus); + assertEquals(accAIFU.accumulateAndGet(u, randMinus, + LambdaUtilities.subLongBinaryOperator()), + initValue + randPlus - randMinus); + break; + case getAndAccumulate: + assertEquals(accAIFU.getAndAccumulate(u, randPlus, + LambdaUtilities.addLongBinaryOperator()), + initValue); + assertEquals(accAIFU.getAndAccumulate(u, randMinus, + LambdaUtilities.subLongBinaryOperator()), + initValue + randPlus); + break; + } + assertEquals(u.accumulation, initValue + randPlus - randMinus); + + class UpdateThread extends Thread{ + OpTimes ops; + + CountDownLatch latch; + UpdateThread(OpTimes ops, CountDownLatch latch){ + this.ops = ops; + this.latch = latch; + } + @Override + public void run() { + int plusTimes = 0; + int minusTimes = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + switch(type) { + case updateAndGet: + accAIFU.updateAndGet(u, plus ? + LambdaUtilities.addLongUnaryOperator(randPlus) : + LambdaUtilities.subLongUnaryOperator(randMinus)); + break; + case getAndUpdate: + accAIFU.getAndUpdate(u, plus ? + LambdaUtilities.addLongUnaryOperator(randPlus) : + LambdaUtilities.subLongUnaryOperator(randMinus)); + break; + case accumulateAndGet: + accAIFU.accumulateAndGet(u, plus ? randPlus : randMinus, + plus ? LambdaUtilities.addLongBinaryOperator() : + LambdaUtilities.subLongBinaryOperator()); + break; + case getAndAccumulate: + accAIFU.getAndAccumulate(u, plus ? randPlus : randMinus, + plus ? LambdaUtilities.addLongBinaryOperator() : + LambdaUtilities.subLongBinaryOperator()); + break; + } + if(plus) + plusTimes++; + else + minusTimes++; + } + ops.plus = plusTimes; + ops.minus = minusTimes; + latch.countDown(); + } + }; + u.accumulation = initValue; + + int plusTimes = 0; + int minusTimes = 0; + OpTimes[] opts = new OpTimes[THREAD_NUM -1]; + CountDownLatch latch = new CountDownLatch(THREAD_NUM -1); + for(int i = 0; i < THREAD_NUM -1; i++) { + opts[i] = new OpTimes(); + new UpdateThread(opts[i], latch).start(); + } + + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + switch(type) { + case updateAndGet: + accAIFU.updateAndGet(u, plus ? + LambdaUtilities.addLongUnaryOperator(randPlus) : + LambdaUtilities.subLongUnaryOperator(randMinus)); + break; + case getAndUpdate: + accAIFU.getAndUpdate(u, plus ? + LambdaUtilities.addLongUnaryOperator(randPlus) : + LambdaUtilities.subLongUnaryOperator(randMinus)); + break; + case accumulateAndGet: + accAIFU.accumulateAndGet(u, plus ? randPlus : randMinus, + plus ? LambdaUtilities.addLongBinaryOperator() : + LambdaUtilities.subLongBinaryOperator()); + break; + case getAndAccumulate: + accAIFU.getAndAccumulate(u, plus ? randPlus : randMinus, + plus ? LambdaUtilities.addLongBinaryOperator() : + LambdaUtilities.subLongBinaryOperator()); + break; + } + if(plus) + plusTimes++; + else + minusTimes++; + } + latch.await(); + for(int i = 0; i < THREAD_NUM -1; i++) { + plusTimes += opts[i].plus; + minusTimes += opts[i].minus; + } + long expected = initValue + plusTimes * randPlus - + minusTimes * randMinus; + assertEquals(expected, u.accumulation); + } + + static class Updater{ + public volatile long accumulation; + } + + static class OpTimes{ + public int plus; + + public int minus; + } +} \ No newline at end of file
--- a/test/java/util/concurrent/AtomicLongFieldUpdater/UpdateAndGetTest.java Thu Apr 04 22:28:40 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @summary test AtomicLongFieldUpdater.updateAndGet()/getAndUpdate(); - * @(#) UpdateAndGetTest.java - * @library ../../ - * @author Tristan Yan - * @run testng UpdateAndGetTest - * @bug 8001666 - */ - -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicLongFieldUpdater; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -public class UpdateAndGetTest { - private static Random rand = new Random(System.currentTimeMillis()); - - private final static int OP_TIMES = 1 << 10; - - private final static int THREAD_NUM = 1 << 4; - - @DataProvider - public Object[][] booleanProvider(){ - return new Object[][]{ - {Boolean.TRUE}, - {Boolean.FALSE} - }; - } - - @Test(dataProvider = "booleanProvider") - @SuppressWarnings({"rawtypes", "unchecked"}) - public void testUpdateAndGet(final boolean updateAndGet) throws InterruptedException, - ExecutionException { - long initValue = rand.nextLong(); - final Updater u = new Updater(); - u.accumulation = initValue; - final AtomicLongFieldUpdater<Updater> accAIFU = AtomicLongFieldUpdater.<Updater>newUpdater((Class<Updater>)(Class<?>)u.getClass(), "accumulation"); - final long randPlus = rand.nextLong(); - final long randMinus = rand.nextLong(); - if(updateAndGet) { - assertEquals(accAIFU.updateAndGet(u, LambdaUtilities.addLongUnaryOperator(randPlus)), initValue + randPlus); - assertEquals(accAIFU.updateAndGet(u, LambdaUtilities.subLongUnaryOperator(randMinus)), initValue + randPlus - randMinus); - } else { - assertEquals(accAIFU.getAndUpdate(u, LambdaUtilities.addLongUnaryOperator(randPlus)), initValue); - assertEquals(accAIFU.getAndUpdate(u, LambdaUtilities.subLongUnaryOperator(randMinus)), initValue + randPlus); - } - assertEquals(u.accumulation, initValue + randPlus - randMinus); - - class UpdateThread extends Thread{ - OpTimes ops; - - CountDownLatch latch; - UpdateThread(OpTimes ops, CountDownLatch latch){ - this.ops = ops; - this.latch = latch; - } - @Override - public void run() { - int plusTimes = 0; - int minusTimes = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(updateAndGet) - accAIFU.updateAndGet(u, plus ? - LambdaUtilities.addLongUnaryOperator(randPlus) : - LambdaUtilities.subLongUnaryOperator(randMinus)); - else - accAIFU.getAndUpdate(u, plus ? - LambdaUtilities.addLongUnaryOperator(randPlus) : - LambdaUtilities.subLongUnaryOperator(randMinus)); - if(plus) - plusTimes++; - else - minusTimes++; - } - ops.plus = plusTimes; - ops.minus = minusTimes; - latch.countDown(); - } - }; - u.accumulation = initValue; - - int plusTimes = 0; - int minusTimes = 0; - OpTimes[] opts = new OpTimes[THREAD_NUM -1]; - CountDownLatch latch = new CountDownLatch(THREAD_NUM -1); - for(int i = 0; i < THREAD_NUM -1; i++) { - opts[i] = new OpTimes(); - new UpdateThread(opts[i], latch).start(); - } - - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(updateAndGet) - accAIFU.updateAndGet(u, plus ? - LambdaUtilities.addLongUnaryOperator(randPlus) : - LambdaUtilities.subLongUnaryOperator(randMinus)); - else - accAIFU.getAndUpdate(u, plus ? - LambdaUtilities.addLongUnaryOperator(randPlus) : - LambdaUtilities.subLongUnaryOperator(randMinus)); - if(plus) - plusTimes++; - else - minusTimes++; - } - latch.await(); - for(int i = 0; i < THREAD_NUM -1; i++) { - plusTimes += opts[i].plus; - minusTimes += opts[i].minus; - } - long expected = initValue + plusTimes * randPlus - - minusTimes * randMinus; - assertEquals(expected, u.accumulation); - } - - static class Updater{ - public volatile long accumulation; - } - - static class OpTimes{ - public int plus; - - public int minus; - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/concurrent/AtomicReference/LambdaTest.java Fri Apr 05 12:39:26 2013 +0800 @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary test for AtomicReference.updateAndGet()/getAndUpdate() and + * AtomicReference.accumulateAndGet()/getAndAccumulate(); + * @(#) LambdaTest.java + * @library ../../ + * @author Tristan Yan + * @run testng LambdaTest + * @bug 8001666 + */ + +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; +import static org.testng.Assert.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class LambdaTest { + private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate}; + + private static Random rand = new Random(System.currentTimeMillis()); + + private final static int OP_TIMES = 1 << 10; + + private final static int THREAD_NUM = 1 << 4; + + @DataProvider + public Object[][] booleanProvider(){ + Object[][] providersParam = new Object[Type.values().length][]; + Object[] a = Type.values(); + for(int i = 0; i < a.length; i++) + providersParam[i] = new Object[]{a[i]}; + return providersParam; + } + + @Test(dataProvider = "booleanProvider") + public void test(final Type type) throws InterruptedException{ + int initPlus = rand.nextInt(); + int initMinus = rand.nextInt(); + final AtomicReference<OpValues> ar + = new AtomicReference<>(new OpValues(initPlus, initMinus)); + final int oprnd = rand.nextInt(); + boolean startFromPlus = rand.nextBoolean(); + switch(type) { + case updateAndGet: + assertEquals(ar.updateAndGet(opUnaryOperator(startFromPlus, oprnd)) + , startFromPlus ? new OpValues(initPlus + oprnd, initMinus) : + new OpValues(initPlus, initMinus - oprnd)); + assertEquals(ar.updateAndGet(opUnaryOperator(!startFromPlus, oprnd)) + , new OpValues(initPlus + oprnd, initMinus - oprnd)); + break; + case getAndUpdate: + assertEquals(ar.getAndUpdate(opUnaryOperator(startFromPlus, oprnd)) + , new OpValues(initPlus, initMinus)); + assertEquals(ar.getAndUpdate(opUnaryOperator(!startFromPlus, oprnd)) + , startFromPlus ? new OpValues(initPlus + oprnd, initMinus) : + new OpValues(initPlus, initMinus - oprnd)); + break; + case accumulateAndGet: + assertEquals(ar.accumulateAndGet( + new OpValues(oprnd, oprnd), + opBinaryOperator(startFromPlus)) + , startFromPlus ? new OpValues(initPlus + oprnd, initMinus) : + new OpValues(initPlus, initMinus - oprnd)); + assertEquals(ar.accumulateAndGet( + new OpValues(oprnd, oprnd), + opBinaryOperator(!startFromPlus)) + , new OpValues(initPlus + oprnd, initMinus - oprnd)); + break; + case getAndAccumulate: + assertEquals(ar.getAndAccumulate( + new OpValues(oprnd, oprnd), + opBinaryOperator(startFromPlus)) + , new OpValues(initPlus, initMinus)); + assertEquals(ar.getAndAccumulate( + new OpValues(oprnd, oprnd), + opBinaryOperator(!startFromPlus)) + , startFromPlus ? new OpValues(initPlus + oprnd, initMinus) : + new OpValues(initPlus, initMinus - oprnd)); + break; + } + class UpdateThread extends Thread{ + CountDownLatch latch; + private int plusTimes = 0; + private int minusTimes = 0; + + UpdateThread(CountDownLatch latch){ + this.latch = latch; + } + @Override + public void run() { + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + switch(type) { + case updateAndGet: + ar.updateAndGet(opUnaryOperator(plus, oprnd)); + break; + case getAndUpdate: + ar.getAndUpdate(opUnaryOperator(plus, oprnd)); + break; + case accumulateAndGet: + ar.accumulateAndGet(new OpValues(oprnd, oprnd), + opBinaryOperator(plus)); + break; + case getAndAccumulate: + ar.getAndAccumulate(new OpValues(oprnd, oprnd), + opBinaryOperator(plus)); + break; + } + if(plus) + plusTimes++; + else + minusTimes++; + } + latch.countDown(); + } + int plusTimes(){ return plusTimes; } + int minusTimes(){ return minusTimes; } + }; + UpdateThread[] threads = new UpdateThread[THREAD_NUM -1]; + CountDownLatch latch = new CountDownLatch(THREAD_NUM -1); + for(int i = 0; i < THREAD_NUM -1; i++) { + threads[i] = new UpdateThread(latch); + threads[i].start(); + } + int plusTimes = 0; + int minusTimes = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean isPlus = rand.nextBoolean(); + switch(type) { + case updateAndGet: + ar.updateAndGet(opUnaryOperator(isPlus, oprnd)); + break; + case getAndUpdate: + ar.getAndUpdate(opUnaryOperator(isPlus, oprnd)); + break; + case accumulateAndGet: + ar.accumulateAndGet(new OpValues(oprnd, oprnd), + opBinaryOperator(isPlus)); + break; + case getAndAccumulate: + ar.getAndAccumulate(new OpValues(oprnd, oprnd), + opBinaryOperator(isPlus)); + break; + } + if(isPlus) + plusTimes++; + else + minusTimes++; + } + latch.await(); + for(int i = 0; i < THREAD_NUM -1; i++) { + plusTimes += threads[i].plusTimes(); + minusTimes += threads[i].minusTimes(); + } + assertEquals(ar.get().getPlusAccumulated(), initPlus + plusTimes * oprnd + oprnd); + assertEquals(ar.get().getMinusAccumulated(), initMinus - minusTimes * oprnd - oprnd); + } + + static final class OpValues{ + final int plusAccumulated; + + final int minusAccumulated; + + OpValues(int plusAccumulated, int minusAccumulated){ + this.plusAccumulated = plusAccumulated; + this.minusAccumulated = minusAccumulated; + } + + OpValues operate(boolean isPlus, int value) { + if(isPlus) + return new OpValues(plusAccumulated + value, minusAccumulated); + else + return new OpValues(plusAccumulated, minusAccumulated - value); + } + + int getPlusAccumulated(){ return plusAccumulated; } + int getMinusAccumulated(){ return minusAccumulated; } + + @Override + public boolean equals(Object o){ + OpValues opv = (OpValues)o; + return (opv.plusAccumulated == plusAccumulated) + && (opv.minusAccumulated == minusAccumulated); + } + } + + public static UnaryOperator<OpValues> opUnaryOperator(boolean isPlus, int value) { + return t -> t.operate(isPlus, value); + } + + public static BinaryOperator<OpValues> opBinaryOperator(boolean isPlus) { + return (t1, t2) -> t1.operate(isPlus, isPlus ? t2.getPlusAccumulated() : t2.getMinusAccumulated()); + } +} \ No newline at end of file
--- a/test/java/util/concurrent/AtomicReference/UpdateAndGetTest.java Thu Apr 04 22:28:40 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @summary test AtomicReference.updateAndGet()/getAndUpdate(); - * @(#) UpdateAndGetTest.java - * @library ../../ - * @author Tristan Yan - * @run testng UpdateAndGetTest - * @bug 8001666 - */ - -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.UnaryOperator; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -public class UpdateAndGetTest { - private static Random rand = new Random(System.currentTimeMillis()); - - private final static int OP_TIMES = 1 << 10; - - private final static int THREAD_NUM = 1 << 4; - - @DataProvider - public Object[][] booleanProvider(){ - return new Object[][]{ - {Boolean.TRUE}, - {Boolean.FALSE} - }; - } - - @Test(dataProvider = "booleanProvider") - public void testUpdateAndGet(final boolean updateAndGet) throws InterruptedException{ - int initPlus = rand.nextInt(); - int initMinus = rand.nextInt(); - final AtomicReference<OpValues> ar - = new AtomicReference<>(new OpValues(initPlus, initMinus)); - final int oprnd = rand.nextInt(); - boolean startFromPlus = rand.nextBoolean(); - if(updateAndGet) { - assertEquals(ar.updateAndGet(opUnaryOperator(startFromPlus, oprnd)) - , startFromPlus ? new OpValues(initPlus + oprnd, initMinus) : - new OpValues(initPlus, initMinus - oprnd)); - assertEquals(ar.updateAndGet(opUnaryOperator(!startFromPlus, oprnd)) - , new OpValues(initPlus + oprnd, initMinus - oprnd)); - } else { - assertEquals(ar.getAndUpdate(opUnaryOperator(startFromPlus, oprnd)) - , new OpValues(initPlus, initMinus)); - assertEquals(ar.getAndUpdate(opUnaryOperator(!startFromPlus, oprnd)) - , startFromPlus ? new OpValues(initPlus + oprnd, initMinus) : - new OpValues(initPlus, initMinus - oprnd)); - } - class UpdateThread extends Thread{ - CountDownLatch latch; - private int plusTimes = 0; - private int minusTimes = 0; - - UpdateThread(CountDownLatch latch){ - this.latch = latch; - } - @Override - public void run() { - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(updateAndGet) - ar.updateAndGet(opUnaryOperator(plus, oprnd)); - else - ar.getAndUpdate(opUnaryOperator(plus, oprnd)); - if(plus) - plusTimes++; - else - minusTimes++; - } - latch.countDown(); - } - int plusTimes(){ return plusTimes; } - int minusTimes(){ return minusTimes; } - }; - UpdateThread[] threads = new UpdateThread[THREAD_NUM -1]; - CountDownLatch latch = new CountDownLatch(THREAD_NUM -1); - for(int i = 0; i < THREAD_NUM -1; i++) { - threads[i] = new UpdateThread(latch); - threads[i].start(); - } - int plusTimes = 0; - int minusTimes = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean isPlus = rand.nextBoolean(); - if(updateAndGet) - ar.updateAndGet(opUnaryOperator(isPlus, oprnd)); - else - ar.getAndUpdate(opUnaryOperator(isPlus, oprnd)); - if(isPlus) - plusTimes++; - else - minusTimes++; - } - latch.await(); - for(int i = 0; i < THREAD_NUM -1; i++) { - plusTimes += threads[i].plusTimes(); - minusTimes += threads[i].minusTimes(); - } - assertEquals(ar.get().getPlusAccumulated(), initPlus + plusTimes * oprnd + oprnd); - assertEquals(ar.get().getMinusAccumulated(), initMinus - minusTimes * oprnd - oprnd); - } - - static final class OpValues{ - final int plusAccumulated; - - final int minusAccumulated; - - OpValues(int plusAccumulated, int minusAccumulated){ - this.plusAccumulated = plusAccumulated; - this.minusAccumulated = minusAccumulated; - } - - OpValues operate(boolean isPlus, int value) { - if(isPlus) - return new OpValues(plusAccumulated + value, minusAccumulated); - else - return new OpValues(plusAccumulated, minusAccumulated - value); - } - - int getPlusAccumulated(){ return plusAccumulated; } - int getMinusAccumulated(){ return minusAccumulated; } - - @Override - public boolean equals(Object o){ - OpValues opv = (OpValues)o; - return (opv.plusAccumulated == plusAccumulated) - && (opv.minusAccumulated == minusAccumulated); - } - } - - public static UnaryOperator<OpValues> opUnaryOperator(boolean isPlus, int value) { - return t -> t.operate(isPlus, value); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/concurrent/AtomicReferenceFieldUpdater/LambdaTest.java Fri Apr 05 12:39:26 2013 +0800 @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary test for AtomicReferenceFieldUpdater.updateAndGet()/getAndUpdate() + * and AtomicReferenceFieldUpdater.accumulateAndGet()/getAndAccumulate(); + * @(#) LambdaTest.java + * @library ../../ + * @author Tristan Yan + * @run testng LambdaTest + * @bug 8001666 + */ + +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; +import static org.testng.Assert.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class LambdaTest { + private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate}; + + private static Random rand = new Random(System.currentTimeMillis()); + + private final static int OP_TIMES = 1 << 10; + + private final static int THREAD_NUM = 1 << 4; + + @DataProvider + public Object[][] booleanProvider(){ + Object[][] providersParam = new Object[Type.values().length][]; + Object[] a = Type.values(); + for(int i = 0; i < a.length; i++) + providersParam[i] = new Object[]{a[i]}; + return providersParam; + } + + @Test(dataProvider = "booleanProvider") + @SuppressWarnings({"rawtypes", "unchecked"}) + public void test(final Type type) throws InterruptedException{ + int initValue = rand.nextInt(); + final Updater u = new Updater(); + u.accumulation = new OpValues(initValue); + final AtomicReferenceFieldUpdater<Updater, OpValues> accARFU + = AtomicReferenceFieldUpdater.<Updater, OpValues>newUpdater((Class<Updater>)(Class<?>)u.getClass(), (Class<OpValues>)(Class<?>)u.accumulation.getClass(), "accumulation"); + + final int oprnd = rand.nextInt(); + boolean startFromPlus = rand.nextBoolean(); + switch(type) { + case updateAndGet: + assertEquals(accARFU.updateAndGet(u,opUnaryOperator(startFromPlus, oprnd)) + , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd)); + assertEquals(accARFU.updateAndGet(u,opUnaryOperator(!startFromPlus, oprnd)) + , new OpValues(initValue)); + break; + case getAndUpdate: + assertEquals(accARFU.getAndUpdate(u,opUnaryOperator(startFromPlus, oprnd)) + , new OpValues(initValue)); + assertEquals(accARFU.getAndUpdate(u,opUnaryOperator(!startFromPlus, oprnd)) + , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd)); + break; + case accumulateAndGet: + assertEquals(accARFU.accumulateAndGet(u, new OpValues(oprnd), + opBinaryOperator(startFromPlus)) + , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd)); + assertEquals(accARFU.accumulateAndGet(u, new OpValues(oprnd), + opBinaryOperator(!startFromPlus)) + , new OpValues(initValue)); + break; + case getAndAccumulate: + assertEquals(accARFU.getAndAccumulate(u, new OpValues(oprnd), + opBinaryOperator(startFromPlus)) + , new OpValues(initValue)); + assertEquals(accARFU.getAndAccumulate(u, new OpValues(oprnd), + opBinaryOperator(!startFromPlus)) + , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd)); + break; + } + class UpdateThread extends Thread{ + CountDownLatch latch; + private int plusTimes = 0; + private int minusTimes = 0; + + UpdateThread(CountDownLatch latch){ + this.latch = latch; + } + @Override + public void run() { + for(int index = 0; index < OP_TIMES; index++) { + boolean plus = rand.nextBoolean(); + switch(type) { + case updateAndGet: + accARFU.updateAndGet(u,opUnaryOperator(plus, oprnd)); + break; + case getAndUpdate: + accARFU.getAndUpdate(u,opUnaryOperator(plus, oprnd)); + break; + case accumulateAndGet: + accARFU.accumulateAndGet(u, new OpValues(oprnd), + opBinaryOperator(plus)); + break; + case getAndAccumulate: + accARFU.getAndAccumulate(u, new OpValues(oprnd), + opBinaryOperator(plus)); + break; + } + if(plus) + plusTimes++; + else + minusTimes++; + } + latch.countDown(); + } + int plusTimes(){ return plusTimes; } + int minusTimes(){ return minusTimes; } + }; + UpdateThread[] threads = new UpdateThread[THREAD_NUM -1]; + CountDownLatch latch = new CountDownLatch(THREAD_NUM -1); + for(int i = 0; i < THREAD_NUM -1; i++) { + threads[i] = new UpdateThread(latch); + threads[i].start(); + } + int plusTimes = 0; + int minusTimes = 0; + for(int index = 0; index < OP_TIMES; index++) { + boolean isPlus = rand.nextBoolean(); + switch(type) { + case updateAndGet: + accARFU.updateAndGet(u,opUnaryOperator(isPlus, oprnd)); + break; + case getAndUpdate: + accARFU.getAndUpdate(u,opUnaryOperator(isPlus, oprnd)); + break; + case accumulateAndGet: + accARFU.accumulateAndGet(u, new OpValues(oprnd), + opBinaryOperator(isPlus)); + break; + case getAndAccumulate: + accARFU.getAndAccumulate(u, new OpValues(oprnd), + opBinaryOperator(isPlus)); + break; + } + if(isPlus) + plusTimes++; + else + minusTimes++; + } + latch.await(); + for(int i = 0; i < THREAD_NUM -1; i++) { + plusTimes += threads[i].plusTimes(); + minusTimes += threads[i].minusTimes(); + } + assertEquals(accARFU.get(u).getAccumulated(), initValue + plusTimes * oprnd - minusTimes * oprnd); + } + + static final class OpValues{ + int accumulated; + + OpValues(int accumulated){ + this.accumulated = accumulated; + } + + OpValues operate(boolean isPlus, int value) { + if(isPlus) + return new OpValues(accumulated + value); + else + return new OpValues(accumulated - value); + } + + int getAccumulated(){ return accumulated; } + + @Override + public boolean equals(Object o){ + OpValues opv = (OpValues)o; + return (opv.accumulated == accumulated); + } + } + + + static class Updater{ + public volatile OpValues accumulation; + } + + public static UnaryOperator<OpValues> opUnaryOperator(boolean isPlus, int value) { + return t -> t.operate(isPlus, value); + } + + public static BinaryOperator<OpValues> opBinaryOperator(boolean isPlus) { + return (t1, t2) -> t1.operate(isPlus, t2.getAccumulated()); + } +} \ No newline at end of file
--- a/test/java/util/concurrent/AtomicReferenceFieldUpdater/UpdateAndGetTest.java Thu Apr 04 22:28:40 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @summary test AtomicReferenceFieldUpdater.updateAndGet()/getAndUpdate(); - * @(#) UpdateAndGetTest.java - * @library ../../ - * @author Tristan Yan - * @run testng UpdateAndGetTest - * @bug 8001666 - */ - -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.function.UnaryOperator; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -public class UpdateAndGetTest { - private static Random rand = new Random(System.currentTimeMillis()); - - private final static int OP_TIMES = 1 << 10; - - private final static int THREAD_NUM = 1 << 4; - - @DataProvider - public Object[][] booleanProvider(){ - return new Object[][]{ - {Boolean.TRUE}, - {Boolean.FALSE} - }; - } - - @Test(dataProvider = "booleanProvider") - @SuppressWarnings({"rawtypes", "unchecked"}) - public void testUpdateAndGet(final boolean updateAndGet) throws InterruptedException{ - int initValue = rand.nextInt(); - final Updater u = new Updater(); - u.accumulation = new OpValues(initValue); - final AtomicReferenceFieldUpdater<Updater, OpValues> accARFU - = AtomicReferenceFieldUpdater.<Updater, OpValues>newUpdater((Class<Updater>)(Class<?>)u.getClass(), (Class<OpValues>)(Class<?>)u.accumulation.getClass(), "accumulation"); - - final int oprnd = rand.nextInt(); - boolean startFromPlus = rand.nextBoolean(); - if(updateAndGet) { - assertEquals(accARFU.updateAndGet(u,opUnaryOperator(startFromPlus, oprnd)) - , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd)); - assertEquals(accARFU.updateAndGet(u,opUnaryOperator(!startFromPlus, oprnd)) - , new OpValues(initValue)); - } else { - assertEquals(accARFU.getAndUpdate(u,opUnaryOperator(startFromPlus, oprnd)) - , new OpValues(initValue)); - assertEquals(accARFU.getAndUpdate(u,opUnaryOperator(!startFromPlus, oprnd)) - , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd)); - } - class UpdateThread extends Thread{ - CountDownLatch latch; - private int plusTimes = 0; - private int minusTimes = 0; - - UpdateThread(CountDownLatch latch){ - this.latch = latch; - } - @Override - public void run() { - for(int index = 0; index < OP_TIMES; index++) { - boolean plus = rand.nextBoolean(); - if(updateAndGet) - accARFU.updateAndGet(u,opUnaryOperator(plus, oprnd)); - else - accARFU.getAndUpdate(u,opUnaryOperator(plus, oprnd)); - if(plus) - plusTimes++; - else - minusTimes++; - } - latch.countDown(); - } - int plusTimes(){ return plusTimes; } - int minusTimes(){ return minusTimes; } - }; - UpdateThread[] threads = new UpdateThread[THREAD_NUM -1]; - CountDownLatch latch = new CountDownLatch(THREAD_NUM -1); - for(int i = 0; i < THREAD_NUM -1; i++) { - threads[i] = new UpdateThread(latch); - threads[i].start(); - } - int plusTimes = 0; - int minusTimes = 0; - for(int index = 0; index < OP_TIMES; index++) { - boolean isPlus = rand.nextBoolean(); - if(updateAndGet) - accARFU.updateAndGet(u,opUnaryOperator(isPlus, oprnd)); - else - accARFU.getAndUpdate(u,opUnaryOperator(isPlus, oprnd)); - if(isPlus) - plusTimes++; - else - minusTimes++; - } - latch.await(); - for(int i = 0; i < THREAD_NUM -1; i++) { - plusTimes += threads[i].plusTimes(); - minusTimes += threads[i].minusTimes(); - } - assertEquals(accARFU.get(u).getAccumulated(), initValue + plusTimes * oprnd - minusTimes * oprnd); - } - - public UpdateAndGetTest() { - } - static final class OpValues{ - int accumulated; - - OpValues(int accumulated){ - this.accumulated = accumulated; - } - - OpValues operate(boolean isPlus, int value) { - if(isPlus) - return new OpValues(accumulated + value); - else - return new OpValues(accumulated - value); - } - - int getAccumulated(){ return accumulated; } - - @Override - public boolean equals(Object o){ - OpValues opv = (OpValues)o; - return (opv.accumulated == accumulated); - } - } - - - static class Updater{ - public volatile OpValues accumulation; - } - - public static UnaryOperator<OpValues> opUnaryOperator(boolean isPlus, int value) { - return t -> t.operate(isPlus, value); - } -}