ReentrantLock和synchronized在低併發的時候性能差距不大,本次主要測試高併發時的性能。
使用ReentrantLock
public class SysDemoTest implements Runnable{
private HashMap<String,Integer> x;
private CountDownLatch latch;
private CountDownLatch end;
private ReentrantLock lock;
SysDemoTest(HashMap<String,Integer> x,CountDownLatch latch,ReentrantLock lock,CountDownLatch end){
this.x = x;
this.latch = latch;
this.lock = lock;
this.end = end;
}
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
CountDownLatch latch = new CountDownLatch(1000);
CountDownLatch end = new CountDownLatch(1000);
HashMap<String,Integer> x = new HashMap<String,Integer>();
x.put("1", 0);
long start = System.currentTimeMillis();
SysDemoTest test = new SysDemoTest(x,latch,lock,end);
for(int i = 0 ;i <1000;i++) {
Thread t = new Thread(test);
t.start();
latch.countDown();
}
try {
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis()-start);
System.out.println(x.get("1"));
}
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0 ;i <100000;i++) {
lock.lock();
try{
Integer z = x.get("1");
x.put("1", ++z);
}finally{
lock.unlock();
}
}
end.countDown();
}
synchronized void add() {
Integer i = x.get("1");
x.put("1", ++i);
}
}
使用synchronized
public class SysDemoTest implements Runnable{
private HashMap<String,Integer> x;
private CountDownLatch latch;
private CountDownLatch end;
private ReentrantLock lock;
SysDemoTest(HashMap<String,Integer> x,CountDownLatch latch,ReentrantLock lock,CountDownLatch end){
this.x = x;
this.latch = latch;
this.lock = lock;
this.end = end;
}
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
CountDownLatch latch = new CountDownLatch(1000);
CountDownLatch end = new CountDownLatch(1000);
HashMap<String,Integer> x = new HashMap<String,Integer>();
x.put("1", 0);
long start = System.currentTimeMillis();
SysDemoTest test = new SysDemoTest(x,latch,lock,end);
for(int i = 0 ;i <1000;i++) {
Thread t = new Thread(test);
t.start();
latch.countDown();
}
try {
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis()-start);
System.out.println(x.get("1"));
}
@Override
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0 ;i <100000;i++) {
add();
}
end.countDown();
}
synchronized void add() {
Integer i = x.get("1");
x.put("1", ++i);
}
}
使用ReentrantLock,計算100000000次,花費5789ms。
使用synchronized,計算100000000次,花費8850ms。
ReentrantLock比synchronized快的主要原因還是:ReentrantLock有利用CAS自旋操作來實現鎖,在大併發的情況下synchronized線程間切換會有很大的資源消耗。