一 相同点
1. 两者都是用来保护资源 ,线程安全的。
都可以起到保护资源,不会因多线程修改而产生冲突的情况。
2. 可以保证可见性
可见性,说起来也简单,简单来说在解锁N之前的所有操作,对于加锁N之后的所有操作(包括其他线程的)都是可见的。
3. 都可重入
synchronized 和 ReentrantLock (Lock)都具备可重入性,可重入是指如果一个线程已经获取了一个锁,再试图获取这个锁,不需要释放,而是直接获取锁。如果不可重入是一个线程获取A锁之后,同一个线程如果想再次获取A锁,必须先释放后,才能再次获取A锁。
二 不同点
1. 用法不同
synchronized 关键字可以加上方法上,不需要指定锁对象,也可以修饰一个同步代码块,并且自定义monitor对象;Lock 锁对象开始加锁lock()和解锁unlock(),一般在finally里面释放锁,防止引起代码死锁。
2. 加锁顺序不同
Lock的锁可以不按照加锁的顺序反向解锁,比如我们先对LockA加锁,再获取LockB锁,释放的时候可以先解锁LockA,再解锁LockB,顺序有一定的灵活度。
synchronized 解锁的顺序和加锁的顺序必须完全相反,不能控制。
synchronized(obj1){
synchronized(obj2){
...
}
}
这里面的加锁顺序是先是obj1,再是obj2,再次obj2解锁,再对obj1解锁,这是JVM实现,不能控制。
3. synchronized锁不够灵活
synchronized 锁一旦被线程获得后,其他线程如果想获得,那么它只能被阻塞,直到持有锁的线程执行完毕或发生异常而释放这个锁。如果持有锁很长,会影响程序执行效率。
Lock类再等锁过程中,如果使用lockInterruptibly()方法,那么如果等待时间太长,可以中断退出,也可以通过tryLock尝试获取锁,获取不到,可以做点别的事情。
4. synchronized锁 只能被一个线程获取
Lock的实现的读锁可以由多个线程持有,而synchronized锁,不行。
5. 原理区别
synchronized是内置锁,由JVM实现加锁和解锁,还分为偏向锁,轻量级锁,重量级锁。
Lock根据实现不同,原理不同 。
6.是否可以设置公平、非公平
公平锁是指多个线程再等待同个锁,根据先来后到来获取锁。非公平锁则不然,ReentrantLock等可以根据实现类可以根据需要设置公平或非公平锁,synchronized则无法设置。
** 7.性能区别**
以前synchronized性能比较低,后面JDK对synchronized有很多优化,比如偏向锁,轻量级锁,重量级锁。
三 总结
- 如果能不用锁,不用用任何所,很多情况下用 java.util.concurrent包里面的机制来实现加解锁;
- 如果synchronized适合就用这个,因为减少编写代码数量,减少出错的概率,使用更安全。
- 如果需要使用Lock特殊功能,比如尝试获取锁,可中断,超时等功能,才能使用Lock。
网友评论