ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/LockLoops.java
Revision: 1.16
Committed: Sat Dec 31 18:54:28 2016 UTC (7 years, 4 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.15: +8 -3 lines
Log Message:
organize imports

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 /*
8 * Simple benchmark comparing various locking techniques.
9 */
10
11 import java.util.concurrent.CyclicBarrier;
12 import java.util.concurrent.ExecutorService;
13 import java.util.concurrent.Executors;
14 import java.util.concurrent.Semaphore;
15 import java.util.concurrent.locks.Lock;
16 import java.util.concurrent.locks.ReentrantLock;
17 import java.util.concurrent.locks.ReentrantReadWriteLock;
18 import java.util.concurrent.locks.StampedLock;
19
20 public final class LockLoops {
21 static final ExecutorService pool = Executors.newCachedThreadPool();
22 static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
23 static boolean print = false;
24 static boolean doBuiltin = true;
25 static boolean doReadWrite = true;
26 static boolean doSemaphore = true;
27 static boolean doStampedLock = true;
28 static boolean doFair = true;
29
30 public static void main(String[] args) throws Exception {
31 int maxThreads = 100;
32 int iters = 1000000;
33 int replications = 1;
34
35 if (args.length > 0)
36 maxThreads = Integer.parseInt(args[0]);
37
38 if (args.length > 1)
39 iters = Integer.parseInt(args[1]);
40
41 if (args.length > 2)
42 replications = Integer.parseInt(args[2]);
43
44 rng.setSeed(3122688L);
45
46 print = false;
47 System.out.println("Warmup...");
48 oneTest(3, 10000);
49 Thread.sleep(1000);
50 oneTest(2, 10000);
51 Thread.sleep(100);
52 oneTest(1, 100000);
53 Thread.sleep(100);
54 oneTest(1, 100000);
55 Thread.sleep(1000);
56 print = true;
57
58 for (int i = 1; i <= maxThreads; ++i) {
59 for (int j = 0; j < replications; ++j) {
60 System.out.println("Threads:" + i);
61 oneTest(i, iters / i);
62 Thread.sleep(100);
63 }
64 }
65 pool.shutdown();
66 }
67
68 static void oneTest(int nthreads, int iters) throws Exception {
69 int v = rng.next();
70
71 if (print)
72 System.out.print("No shared vars ");
73 new NoLockLoop().test(v, nthreads, iters * 10);
74 Thread.sleep(10);
75
76 if (print)
77 System.out.print("No Lock + volatile ");
78 new NoLockVolatileLoop().test(v, nthreads, iters);
79 Thread.sleep(10);
80
81 if (doBuiltin) {
82 if (print)
83 System.out.print("builtin lock ");
84 new BuiltinLockLoop().test(v, nthreads, iters);
85 Thread.sleep(10);
86 }
87
88 if (print)
89 System.out.print("ReentrantLock ");
90 new ReentrantLockLoop().test(v, nthreads, iters);
91 Thread.sleep(10);
92
93 if (doReadWrite) {
94 if (print)
95 System.out.print("ReentrantWriteLock ");
96 new ReentrantWriteLockLoop().test(v, nthreads, iters);
97 Thread.sleep(10);
98
99 if (print)
100 System.out.print("ReentrantReadLock ");
101 new ReentrantReadLockLoop().test(v, nthreads, iters);
102 Thread.sleep(10);
103
104 if (print)
105 System.out.print("ReentrantReadWriteLock");
106 new ReentrantReadWriteLockLoop().test(v, nthreads, iters);
107 Thread.sleep(10);
108 }
109
110 if (doSemaphore) {
111 if (print)
112 System.out.print("Semaphore ");
113 new SemaphoreLoop().test(v, nthreads, iters);
114 Thread.sleep(10);
115
116 if (print)
117 System.out.print("FairSemaphore ");
118 new FairSemaphoreLoop().test(v, nthreads, iters);
119 Thread.sleep(10);
120 }
121
122 if (doFair) {
123 if (print)
124 System.out.print("FairReentrantLock ");
125 new FairReentrantLockLoop().test(v, nthreads, iters);
126 Thread.sleep(10);
127
128 if (doReadWrite) {
129 if (print)
130 System.out.print("FairRWriteLock ");
131 new FairReentrantWriteLockLoop().test(v, nthreads, iters);
132 Thread.sleep(10);
133
134 if (print)
135 System.out.print("FairRReadWriteLock ");
136 new FairReentrantReadWriteLockLoop().test(v, nthreads, iters);
137 Thread.sleep(10);
138 }
139 }
140
141 if (doStampedLock) {
142 if (print)
143 System.out.print("StampedLockWrite ");
144 new StampedLockWriteLoop().test(v, nthreads, iters);
145 Thread.sleep(10);
146
147 if (print)
148 System.out.print("StampedLockRead ");
149 new StampedLockReadLoop().test(v, nthreads, iters);
150 Thread.sleep(10);
151
152 if (print)
153 System.out.print("StampedLockOptRead");
154 new StampedLockOptimisticReadLoop().test(v, nthreads, iters);
155 Thread.sleep(10);
156
157 if (print)
158 System.out.print("StampedLockReadWrite");
159 new StampedLockReadWriteLoop().test(v, nthreads, iters);
160 Thread.sleep(10);
161 }
162 }
163
164 abstract static class LockLoop implements Runnable {
165 int v;
166 int iters;
167 volatile int result;
168 final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
169 CyclicBarrier barrier;
170
171 final void test(int initialValue, int nthreads, int iters) throws Exception {
172 v = initialValue;
173 this.iters = iters;
174 barrier = new CyclicBarrier(nthreads+1, timer);
175 for (int i = 0; i < nthreads; ++i)
176 pool.execute(this);
177 barrier.await();
178 barrier.await();
179 long time = timer.getTime();
180 if (print) {
181 long tpi = time / (iters * nthreads);
182 System.out.print("\t" + LoopHelpers.rightJustify(tpi) + " ns per update");
183 // double secs = (double) time / 1000000000.0;
184 // System.out.print("\t " + secs + "s run time");
185 System.out.println();
186 }
187
188 if (result == 0) // avoid overoptimization
189 System.out.println("useless result: " + result);
190 }
191 abstract int loop(int n);
192 public final void run() {
193 try {
194 barrier.await();
195 result += loop(iters);
196 barrier.await();
197 }
198 catch (Exception ie) {
199 return;
200 }
201 }
202
203 }
204
205 private static class BuiltinLockLoop extends LockLoop {
206 final int loop(int n) {
207 int sum = 0;
208 while (n-- > 0) {
209 synchronized (this) {
210 v = LoopHelpers.compute1(v);
211 }
212 sum += LoopHelpers.compute2(v);
213 }
214 return sum;
215 }
216 }
217
218 private static class NoLockLoop extends LockLoop {
219 final int loop(int n) {
220 int sum = 0;
221 int y = v;
222 while (n-- > 0) {
223 y = LoopHelpers.compute1(y);
224 sum += LoopHelpers.compute2(y);
225 }
226 return sum;
227 }
228 }
229
230 private static class NoLockVolatileLoop extends LockLoop {
231 private volatile int vv;
232 final int loop(int n) {
233 int sum = 0;
234 while (n-- > 0) {
235 int y = LoopHelpers.compute1(vv);
236 vv = y;
237 sum += LoopHelpers.compute2(y);
238 }
239 return sum;
240 }
241 }
242
243 private static class ReentrantLockLoop extends LockLoop {
244 private final ReentrantLock lock = new ReentrantLock();
245 final int loop(int n) {
246 int sum = 0;
247 while (n-- > 0) {
248 lock.lock();
249 try {
250 v = LoopHelpers.compute1(v);
251 }
252 finally {
253 lock.unlock();
254 }
255 sum += LoopHelpers.compute2(v);
256 }
257 return sum;
258 }
259 }
260
261 private static class FairReentrantLockLoop extends LockLoop {
262 private final ReentrantLock lock = new ReentrantLock(true);
263 final int loop(int n) {
264 int sum = 0;
265 while (n-- > 0) {
266 lock.lock();
267 try {
268 v = LoopHelpers.compute1(v);
269 }
270 finally {
271 lock.unlock();
272 }
273 sum += LoopHelpers.compute2(v);
274 }
275 return sum;
276 }
277 }
278
279 private static class ReentrantWriteLockLoop extends LockLoop {
280 private final Lock lock = new ReentrantReadWriteLock().writeLock();
281 final int loop(int n) {
282 int sum = 0;
283 while (n-- > 0) {
284 lock.lock();
285 try {
286 v = LoopHelpers.compute1(v);
287 }
288 finally {
289 lock.unlock();
290 }
291 sum += LoopHelpers.compute2(v);
292 }
293 return sum;
294 }
295 }
296
297 private static class ReentrantReadLockLoop extends LockLoop {
298 private final Lock lock = new ReentrantReadWriteLock().readLock();
299 final int loop(int n) {
300 int sum = 0;
301 while (n-- > 0) {
302 lock.lock();
303 try {
304 v = LoopHelpers.compute1(v);
305 }
306 finally {
307 lock.unlock();
308 }
309 sum += LoopHelpers.compute2(v);
310 }
311 return sum;
312 }
313 }
314
315 private static class ReentrantReadWriteLockLoop extends LockLoop {
316 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
317 final int loop(int n) {
318 int sum = 0;
319 while (n-- > 0) {
320 int x;
321 lock.readLock().lock();
322 try {
323 x = LoopHelpers.compute1(v);
324 }
325 finally {
326 lock.readLock().unlock();
327 }
328 lock.writeLock().lock();
329 try {
330 v = x;
331 }
332 finally {
333 lock.writeLock().unlock();
334 }
335 sum += LoopHelpers.compute2(v);
336 }
337 return sum;
338 }
339 }
340
341 private static class FairReentrantWriteLockLoop extends LockLoop {
342 final Lock lock = new ReentrantReadWriteLock(true).writeLock();
343 final int loop(int n) {
344 int sum = 0;
345 while (n-- > 0) {
346 lock.lock();
347 try {
348 v = LoopHelpers.compute1(v);
349 }
350 finally {
351 lock.unlock();
352 }
353 sum += LoopHelpers.compute2(v);
354 }
355 return sum;
356 }
357 }
358
359 private static class SemaphoreLoop extends LockLoop {
360 private final Semaphore sem = new Semaphore(1, false);
361 final int loop(int n) {
362 int sum = 0;
363 try {
364 while (n-- > 0) {
365 sem.acquire();
366 try {
367 v = LoopHelpers.compute1(v);
368 }
369 finally {
370 sem.release();
371 }
372 sum += LoopHelpers.compute2(v);
373 }
374 }
375 catch (InterruptedException ie) {
376 return sum;
377 }
378 return sum;
379 }
380 }
381
382 private static class FairSemaphoreLoop extends LockLoop {
383 private final Semaphore sem = new Semaphore(1, true);
384 final int loop(int n) {
385 int sum = 0;
386 try {
387 while (n-- > 0) {
388 sem.acquire();
389 try {
390 v = LoopHelpers.compute1(v);
391 }
392 finally {
393 sem.release();
394 }
395 sum += LoopHelpers.compute2(v);
396 }
397 }
398 catch (InterruptedException ie) {
399 return sum;
400 }
401 return sum;
402 }
403 }
404
405 private static class FairReentrantReadWriteLockLoop extends LockLoop {
406 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
407 final int loop(int n) {
408 int sum = 0;
409 while (n-- > 0) {
410 int x;
411 lock.readLock().lock();
412 try {
413 x = LoopHelpers.compute1(v);
414 }
415 finally {
416 lock.readLock().unlock();
417 }
418 lock.writeLock().lock();
419 try {
420 v = x;
421 }
422 finally {
423 lock.writeLock().unlock();
424 }
425 sum += LoopHelpers.compute2(v);
426 }
427 return sum;
428 }
429 }
430
431 private static class StampedLockWriteLoop extends LockLoop {
432 private final StampedLock lock = new StampedLock();
433 final int loop(int n) {
434 int sum = 0;
435 while (n-- > 0) {
436 long stamp = lock.writeLock();
437 try {
438 v = LoopHelpers.compute1(v);
439 }
440 finally {
441 lock.unlockWrite(stamp);
442 }
443 sum += LoopHelpers.compute2(v);
444 }
445 return sum;
446 }
447 }
448
449 private static class StampedLockReadLoop extends LockLoop {
450 private final StampedLock lock = new StampedLock();
451 final int loop(int n) {
452 int sum = 0;
453 while (n-- > 0) {
454 long stamp = lock.readLock();
455 try {
456 v = LoopHelpers.compute1(v);
457 }
458 finally {
459 lock.unlockRead(stamp);
460 }
461 sum += LoopHelpers.compute2(v);
462 }
463 return sum;
464 }
465 }
466
467 private static class StampedLockOptimisticReadLoop extends LockLoop {
468 private final StampedLock lock = new StampedLock();
469 final int loop(int n) {
470 int sum = 0;
471 while (n-- > 0) {
472 long stamp;
473 do {
474 stamp = lock.tryOptimisticRead();
475 v = LoopHelpers.compute1(v);
476 } while (!lock.validate(stamp));
477 sum += LoopHelpers.compute2(v);
478 }
479 return sum;
480 }
481 }
482
483 private static class StampedLockReadWriteLoop extends LockLoop {
484 private final StampedLock lock = new StampedLock();
485 final int loop(int n) {
486 int sum = 0;
487 while (n-- > 0) {
488 int x;
489 long stamp = lock.readLock();
490 try {
491 x = LoopHelpers.compute1(v);
492 }
493 finally {
494 lock.unlockRead(stamp);
495 }
496 stamp = lock.writeLock();
497 try {
498 v = x;
499 } finally {
500 lock.unlockWrite(stamp);
501 }
502 sum += LoopHelpers.compute2(v);
503 }
504 return sum;
505 }
506 }
507 }