Synchronized 是依赖于JVM实现的,表现为原生语法层面的互斥锁。开发者是没法直接看到相关源码,可是咱们能够经过利用javap工具查看生成的class文件信息来分析Synchronize的实现。同步代码块是使用monitorenter和monitorexit指令实现的,同步方法依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。html
ReenTrantLock 是基于JDK实现的,一个表现为API层面的互斥锁,经过查阅源码就能够了解到。java
public class Lock1 {
private static Lock lock = new ReentrantLock();
private static int num1 = 0;
private static int num2 = 0;
public static void main(String[] args) {
lockDemo();
SyncDemo();
}
/** * 本机测试下20万自增基本能肯定性能,可是不是特别明显,50万差距仍是挺大的 * 20万如下数据synchronized优于Lock * 20万以上数据Lock优于synchronized */
public static void lockDemo(){
long start = System.currentTimeMillis();
for(int i=0;i<500000;i++){
final int num = i;
new Runnable() {
@Override
public void run() {
lock(num);
}
}.run();
}
long end = System.currentTimeMillis();
System.out.println("累加:"+num1);
System.out.println("ReentrantLock锁:"+ (end-start));
}
public static void SyncDemo(){
long start = System.currentTimeMillis();
for(int i=0;i<500000;i++){
final int num = i;
new Runnable() {
@Override
public void run() {
sync(num);
}
}.run();
}
long end = System.currentTimeMillis();
System.out.println("累加:"+num2);
System.out.println("synchronized锁:"+ (end-start));
}
public static void lock(int i){
lock.lock();
num1 ++;
lock.unlock();
}
public static synchronized void sync(int i){
num2 ++;
}
}复制代码
10万++测试数据:api
累加:100000
ReentrantLock锁:13
累加:100000
synchronized锁:8复制代码
50万++测试数据:bash
累加:500000
ReentrantLock锁:20
累加:500000
synchronized锁:28复制代码
看数据很明显在高并发下,ReentrantLock 的性能是要优于 synchronized 的,虽然仅仅是几毫秒的差距,固然这里我并无对比CPU的使用状况。并发
可重入性oracle
ReenTrantLock 的字面意思就是再进入的锁,synchronized关键字所使用的锁也是可重入的,二者关于这个的区别不大。ide
功能区别高并发
Synchronized的使用比较方便,不须要开发者手动加锁和释放锁,而ReenTrantLock须要手工声明来加锁和释放锁(lock() 和 unlock() 方法配合 try/finally 语句块来实现)工具
ReenTrantLock 在锁的细粒度和灵活度上要优于Synchronized。此外,还增长了一些高级特性,主要有如下3项:等待可中断、可实现公平锁以及锁能够绑定多个条件。性能
发展历史
关于synchronized 与ReentrantLock
在JDK 1.6以后,虚拟机对于synchronized关键字进行总体优化后,在性能上synchronized与ReentrantLock已没有明显差距,所以在使用选择上,须要根据场景而定,大部分状况下咱们依然建议是synchronized关键字,缘由之一是使用方便语义清晰,二是性能上虚拟机已为咱们自动优化。而ReentrantLock提供了多样化的同步特性,如超时获取锁、能够被中断获取锁(synchronized的同步是不能中断的)、等待唤醒机制的多个条件变量(Condition)等,所以当咱们确实须要使用到这些功能是,能够选择ReentrantLock。