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 */ 33 34 /* 35 * @test 36 * @bug 4486658 37 * @compile -source 1.5 SimpleReentrantLockLoops.java 38 * @run main/timeout=4500 SimpleReentrantLockLoops 39 * @summary multiple threads using a single lock 40 */ 41 42 import java.util.concurrent.*; 43 import java.util.concurrent.locks.*; 44 import java.util.*; 45 46 public final class SimpleReentrantLockLoops { 47 static final ExecutorService pool = Executors.newCachedThreadPool(); 48 static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); 49 static boolean print = false; 50 static int iters = 1000000; 51 52 public static void main(String[] args) throws Exception { 53 int maxThreads = 5; 54 if (args.length > 0) 55 maxThreads = Integer.parseInt(args[0]); 56 57 print = true; 58 59 int reps = 2; 60 for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) { 61 int n = reps; 62 if (reps > 1) --reps; 63 while (n-- > 0) { 64 System.out.print("Threads: " + i); 65 new ReentrantLockLoop(i).test(); 66 Thread.sleep(100); 67 } 68 } 69 pool.shutdown(); 70 if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) 71 throw new Error(); 72 } 73 74 static final class ReentrantLockLoop implements Runnable { 75 private int v = rng.next(); 76 private volatile int result = 17; 77 private final ReentrantLock lock = new ReentrantLock(); 78 private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); 79 private final CyclicBarrier barrier; 80 private final int nthreads; 81 ReentrantLockLoop(int nthreads) { 82 this.nthreads = nthreads; 83 barrier = new CyclicBarrier(nthreads+1, timer); 84 } 85 86 final void test() throws Exception { 87 for (int i = 0; i < nthreads; ++i) 88 pool.execute(this); 89 barrier.await(); 90 barrier.await(); 91 if (print) { 92 long time = timer.getTime(); 93 long tpi = time / ((long)iters * nthreads); 94 System.out.print("\t" + LoopHelpers.rightJustify(tpi) + " ns per lock"); 95 double secs = (double)(time) / 1000000000.0; 96 System.out.println("\t " + secs + "s run time"); 97 } 98 99 int r = result; 100 if (r == 0) // avoid overoptimization 101 System.out.println("useless result: " + r); 102 } 103 104 public final void run() { 105 try { 106 barrier.await(); 107 int sum = v; 108 int x = 0; 109 int n = iters; 110 do { 111 lock.lock(); 112 try { 113 if ((n & 255) == 0) 114 v = x = LoopHelpers.compute2(LoopHelpers.compute1(v)); 115 else 116 v = x += ~(v - n); 117 } 118 finally { 119 lock.unlock(); 120 } 121 // Once in a while, do something more expensive 122 if ((~n & 255) == 0) { 123 sum += LoopHelpers.compute1(LoopHelpers.compute2(x)); 124 } 125 else 126 sum += sum ^ x; 127 } while (n-- > 0); 128 barrier.await(); 129 result += sum; 130 } 131 catch (Exception ie) { 132 return; 133 } 134 } 135 } 136 137 }