kaka的gravatar头像
kaka 2014-04-26 16:37:54

java多线程ReentrantLock、sync、ReentrantReadWriteLock性能比较

今天在了解ReentrantReadWriteLock的时候,看到了一篇文章,模拟了ReentrantLock、synchronized、ReentrantReadWriteLock三种锁在不同场景下的性能情况,对了解这三种锁在不同场景下的性能会有一定帮助。

代码:

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class CurrentObject {

	private static Random random = new Random();

	public final static int READ_NUM = 180;// 读线程数

	public final static int WRITE_NUM = 20;// 写线程数

	private int value;//并发需要读写的值

	private ReadWriteLock lock = new ReentrantReadWriteLock();

	private Lock locknew = new ReentrantLock();
	
	/**
	 * 用于读/写平均耗时的展现
	 */
	public static void display() {
		System.out.println("读平均耗时:"
				+ (TimeCostUtils.getReadLong().get() / READ_NUM) + " ns");

		System.out.println("写平均耗时:"
				+ (TimeCostUtils.getWriteLong().get() / WRITE_NUM) + " ns");
	}
	
	/**
	 * 通过ReentrantReadWriteLock添加读锁
	 * @return value
	 * {@link ReentrantReadWriteLock}
	 */
	public int getValueLock() {
		lock.readLock().lock();
		try {
			return value;
		} finally {
			lock.readLock().unlock();
		}
	}
	
	/**
	 * 通过ReentrantReadWriteLock添加写锁
	 * @param value
	 */
	public void setValueLock(int value) {
		lock.writeLock().lock();
		try {
			this.value = value;
		} finally {
			lock.writeLock().unlock();
		}

	}
	
	/**
	 * 通过ReentrantLock添加读锁
	 * @return value
	 * {@link ReadWriteLock}
	 */
	public int getValueNew() {
		locknew.lock();
		try {
			return value;
		} finally {
			locknew.unlock();
		}
	}
	
	/**
	 * 通过ReentrantLock添加写锁
	 * @param value
	 */
	public void setValueNew(int value) {
		locknew.lock();
		try {
			this.value = value;
		} finally {
			locknew.unlock();
		}

	}

	/**
	 * 通过synchronized添加读锁
	 * @return value
	 */
	public synchronized int getValueSyn() {
		return value;
	}
	
	/**
	 * 通过synchronized添加写锁
	 * @param value
	 */
	public synchronized void setValueSyn(int value) {
		this.value = value;
	}
	
	/**
	 * 测试方法
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {

		//防止线程池大小过大,CPU过多的上下文切换导致的开销影响,线程池大小必须同总共开启的对象
		int maxProcessor = READ_NUM + WRITE_NUM;
		final ExecutorService newFixedThreadPool = Executors
				.newFixedThreadPool(maxProcessor);

		final CountDownLatch latch = new CountDownLatch(READ_NUM + WRITE_NUM);// 最后关闭线程池
		
		final CyclicBarrier barrier = new CyclicBarrier(READ_NUM + WRITE_NUM);// 等待所有线程启动后并发读写

		final CurrentObject concurrentObject = new CurrentObject();

		for (int i = 0; i < READ_NUM; i++) {
			newFixedThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					try {
						barrier.await();
					} catch (Exception e) {
						e.printStackTrace();
					}

					TimeCostUtils.start(TimeCostUtils.READ);
					concurrentObject.getValueLock();
					TimeCostUtils.end();

					latch.countDown();
				}
			});
		}

		for (int i = 0; i < WRITE_NUM; i++) {
			newFixedThreadPool.execute(new Runnable() {

				@Override
				public void run() {

					int nextInt = random.nextInt(1000);
					try {
						barrier.await();
					} catch (Exception e) {
						e.printStackTrace();
					}

					TimeCostUtils.start(TimeCostUtils.WRITE);
					concurrentObject.setValueLock(nextInt);
					TimeCostUtils.end();

					latch.countDown();
				}
			});
		}

		latch.await();

		newFixedThreadPool.shutdown();

		// 系统退出前,关闭线程池及计算平均耗时、总耗时
		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

			@Override
			public void run() {

				display();
			}
		}));

	}

}

import java.util.concurrent.atomic.AtomicLong;

public class TimeCostUtils {
	private static AtomicLong readLong = new AtomicLong();

	private static AtomicLong writeLong = new AtomicLong();

	public final static String WRITE = "write";

	public final static String READ = "read";

	static ThreadLocal<TimesRecords> recordMap = new ThreadLocal<TimesRecords>();

	public static void start(String prefix) {

		TimesRecords timesRecords = new TimesRecords(prefix, System.nanoTime());
		recordMap.set(timesRecords);
	}

	public static void end() {
		TimesRecords timesRecords = recordMap.get();
		long cost = System.nanoTime() - timesRecords.getCost();

		// 计算每次的开销时间
		if (timesRecords.getName().equals(WRITE)) {
			writeLong.addAndGet(cost);
		} else {
			readLong.addAndGet(cost);
		}
	}

	public static AtomicLong getReadLong() {
		return readLong;
	}

	public static AtomicLong getWriteLong() {
		return writeLong;
	}

	static class TimesRecords {

		private String name;

		private long cost;

		public TimesRecords(String name, long cost) {
			this.name = name;
			this.cost = cost;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public long getCost() {
			return cost;
		}

		public void setCost(long cost) {
			this.cost = cost;
		}

	}
}

测试数据:

java多线程ReentrantLock、sync、ReentrantReadWriteLock性能比较

原文:http://www.inter12.org/archives/292


最代码官方编辑于2016-9-23 10:26:37


打赏

最代码最近下载分享源代码列表最近下载
最代码最近浏览分享源代码列表最近浏览
yyh1252  LV8 2023年8月1日
lingqianjue  LV3 2022年6月14日
liys1234  LV9 2022年4月27日
tianli3000  LV7 2021年7月22日
zhenghongixin4065  LV9 2021年1月25日
123暖壶别炸  LV7 2020年11月16日
jiafby  LV2 2020年10月13日
1798672867  LV21 2020年10月9日
dkq1314520  LV7 2020年7月24日
lll111  LV16 2020年7月17日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友