今天在了解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 recordMap = new ThreadLocal();
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;
}
}
}
测试数据:
由最代码官方编辑于2016-9-23 10:26:37