java各种锁机制的性能比较

下面基于jdk8,8G内存,i5处理器对java的synchronized、semaphore、reentrantLock、atomicXXX进行对比,结论和注释都比较全,其中注意使用countDownLatch来控制子线程都执行后(累加到addTime次),主线程再进行时间计算,并且注意把latch.countDown()方法放进子线程的run方法的最后,否则会出现子线程任务没执行完,而latch已经减为0了,此时主线程计算出来的时间是不准确的。下面贴上代码:
package exercises;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 比较不同锁机制的速度
 * 结论:synchronized最慢,semaphore与reentrantLock相近,atomic在自加自减方面最快
 * @author holien
 * @create_Time 2017年9月19日 下午12:38:07
 */
public class CompareLocks {
	static int threadNum = 8;
	static int addTime = 1000000; // 自加次数
	static int countWithSema = 0;
	static int countWithSyn = 0;
	static int countWithReen = 0;
	static AtomicInteger countWithAtomic = new AtomicInteger(0);
	static final Semaphore semaLock = new Semaphore(1);
	static final Object synLock = new Object();
	static final ReentrantLock reenLock = new ReentrantLock();

	public static void compareBetweenSemaphoreAndSyn() {
		// four latches ensure adding to 1000000 then get the spending time
		CountDownLatch latch1 = new CountDownLatch(addTime);
		CountDownLatch latch2 = new CountDownLatch(addTime);
		CountDownLatch latch3 = new CountDownLatch(addTime);
		CountDownLatch latch4 = new CountDownLatch(addTime);
		// thread pool
		ExecutorService executor = Executors.newFixedThreadPool(threadNum);
		// synchronized
		Long startTime1 = System.currentTimeMillis();
		for (int i = 0; i < addTime; i++) {
			executor.execute(() -> {
				addWithSyn();
				latch1.countDown();
			});
		}
		try {
			latch1.await();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		System.out.println("time taked by synchronized: " + (System.currentTimeMillis() - startTime1));
		System.out.println(countWithSyn);
		// semaphore
		Long startTime2 = System.currentTimeMillis();
		for (int i = 0; i < addTime; i++) {
			executor.execute(() -> {
				addWithSema();
				latch2.countDown();
			});
		}
		try {
			latch2.await();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		System.out.println("time taked by semaphore: " + (System.currentTimeMillis() - startTime2));
		System.out.println(countWithSema);
		// reentrantLock
		Long startTime3 = System.currentTimeMillis();
		for (int i = 0; i < addTime; i++) {
			executor.execute(() -> {
				addWithLock();
				latch3.countDown();
			});
		}
		try {
			latch3.await();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		System.out.println("time taked by reentrantLock: " + (System.currentTimeMillis() - startTime3));
		System.out.println(countWithReen);
		// reentrantLock
		Long startTime4 = System.currentTimeMillis();
		for (int i = 0; i < addTime; i++) {
			executor.execute(() -> {
				addWithAtomic();
				latch4.countDown();
			});
		}
		try {
			latch4.await();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		System.out.println("time taked by AtomicInteger: " + (System.currentTimeMillis() - startTime4));
		System.out.println(countWithAtomic.get());

		executor.shutdown();
	}

	private static void addWithSyn() {
		synchronized (synLock) {
			countWithSyn++;
		}
	}

	private static void addWithLock() {
		reenLock.lock();
		countWithReen++;
		reenLock.unlock();
	}

	private static void addWithAtomic() {
		countWithAtomic.getAndIncrement();
	}

	private static void addWithSema() {
		try {
			semaLock.acquire(); // 产生一个信号
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		countWithSema++;
		semaLock.release(); // 解除一个信号
	}

	public static void main(String[] args) throws Exception {
		compareBetweenSemaphoreAndSyn();
	}

}

你可能感兴趣的:(java)