Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.j256;
- import java.util.Random;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Semaphore;
- import java.util.concurrent.TimeUnit;
- import java.util.concurrent.atomic.AtomicInteger;
- /**
- * Quick comparison between synchronized, synchronized lock array, AtomicInteger array,
- * and Semaphore array increment loops.
- *
- * My overall point in this is that 10 MILLION iterations show a difference. The unit cost
- * of the synchronized block is negligible.
- *
- * @author graywatson
- */
- public class IncrementLockingComparison {
- final int NUM_INTEGERS = 100000;
- final int NUM_THREADS = 10;
- final int[] ints = new int[NUM_INTEGERS];
- final AtomicInteger[] atomicIntegers = new AtomicInteger[ints.length];
- final Semaphore[] semaphores = new Semaphore[ints.length];
- final Object[] locks = new Object[ints.length];
- {
- for (int i = 0; i < atomicIntegers.length; i++) {
- atomicIntegers[i] = new AtomicInteger(0);
- }
- for (int i = 0; i < semaphores.length; i++) {
- semaphores[i] = new Semaphore(1);
- }
- for (int i = 0; i < locks.length; i++) {
- locks[i] = new Object();
- }
- }
- public static void main(String[] args) throws Exception {
- IncrementLockingComparison foo = new IncrementLockingComparison();
- foo.doSingleLockIncrement();
- foo.doMultipleLockIncrement();
- foo.doAtomicIncrement();
- foo.doSemaphoreIncrement();
- }
- private void doSingleLockIncrement() throws Exception {
- long before = System.currentTimeMillis();
- ExecutorService pool = Executors.newCachedThreadPool();
- for (int i = 0; i < NUM_THREADS; i++) {
- pool.submit(new SingleLockIncrement());
- }
- pool.shutdown();
- pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
- long after = System.currentTimeMillis();
- System.out.println("Single lock = " + (after - before));
- }
- private void doMultipleLockIncrement() throws Exception {
- long before = System.currentTimeMillis();
- ExecutorService pool = Executors.newCachedThreadPool();
- for (int i = 0; i < NUM_THREADS; i++) {
- pool.submit(new MultipleLockIncrement());
- }
- pool.shutdown();
- pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
- long after = System.currentTimeMillis();
- System.out.println("Lock array = " + (after - before));
- }
- private void doAtomicIncrement() throws Exception {
- long before = System.currentTimeMillis();
- ExecutorService pool = Executors.newCachedThreadPool();
- for (int i = 0; i < NUM_THREADS; i++) {
- pool.submit(new AtomicIncrement());
- }
- pool.shutdown();
- pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
- long after = System.currentTimeMillis();
- System.out.println("AtomicInteger array = " + (after - before));
- }
- private void doSemaphoreIncrement() throws Exception {
- long before = System.currentTimeMillis();
- ExecutorService pool = Executors.newCachedThreadPool();
- for (int i = 0; i < NUM_THREADS; i++) {
- pool.submit(new SemaphoreIncrement());
- }
- pool.shutdown();
- pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
- long after = System.currentTimeMillis();
- System.out.println("Semaphore array = " + (after - before));
- }
- private void doLocksIncrement() throws Exception {
- long before = System.currentTimeMillis();
- ExecutorService pool = Executors.newCachedThreadPool();
- for (int i = 0; i < NUM_THREADS; i++) {
- pool.submit(new MultipleLockIncrement());
- }
- pool.shutdown();
- pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
- long after = System.currentTimeMillis();
- System.out.println(after - before);
- }
- private class SingleLockIncrement implements Runnable {
- @Override
- public void run() {
- Random random = new Random();
- for (int i = 0; i < 10000000; i++) {
- synchronized (ints) {
- ints[random.nextInt(ints.length)]++;
- }
- }
- }
- }
- private class MultipleLockIncrement implements Runnable {
- @Override
- public void run() {
- Random random = new Random();
- assert ints.length == locks.length;
- for (int i = 0; i < 10000000; i++) {
- int which = random.nextInt(ints.length);
- synchronized (locks[which]) {
- ints[which]++;
- }
- }
- }
- }
- private class AtomicIncrement implements Runnable {
- @Override
- public void run() {
- Random random = new Random();
- for (int i = 0; i < 10000000; i++) {
- atomicIntegers[random.nextInt(atomicIntegers.length)].incrementAndGet();
- }
- }
- }
- private class SemaphoreIncrement implements Runnable {
- @Override
- public void run() {
- Random random = new Random();
- assert ints.length == semaphores.length;
- for (int i = 0; i < 10000000; i++) {
- int which = random.nextInt(ints.length);
- try {
- semaphores[which].acquire();
- } catch (InterruptedException e) {
- return;
- }
- try {
- ints[which]++;
- } finally {
- semaphores[which].release();
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement