Lock与synchronized的区别

来源:互联网 发布:php读取本地json文件 编辑:程序博客网 时间:2024/06/09 20:21

对比项
synchronized
Lock
时间
早期jdk版本中就提供的同步机制
jdk5以后的版本中提供的同步机制
释放锁
jvm层面实现的,同步代码执行
完后自动释放锁
代码实现的,需要手动调用
unlock方法释放锁,最好在finally中释放锁
读写锁
不区分读写锁
提供读锁和写锁,多读少写的情况时有更高的效率
锁判断
无法判断
可判断
锁类型
可重入、不可中断、非公平
可重入,可中断,可公平(两者皆可)
性能
少量同步
大量同步

Lock的公平锁与非公平锁:
公平锁(FairSync):直接将获取锁的操作放到等待队列中,谁先抢到锁谁先执行。
非公平锁(NoFairSync): 先获取锁,获取到则执行,未获取到则放入等待队列。

因为从线程进入了RUNNABLE状态,可以执行开始,到实际线程执行是要比较久的时间的。而且,在一个锁释放之后,其他的线程会需要重新来获取锁。其中经历了持有锁的线程释放锁,其他线程从挂起恢复到RUNNABLE状态,其他线程请求锁,获得锁,线程执行,这一系列步骤。如果这个时候,存在一个线程直接请求锁,可能就避开挂起到恢复RUNNABLE状态的这段消耗,所以性能更优化。

ReentrantLock()默认使用的非公平锁。

Lock的读写锁
读读操作非互斥,读写操作互斥,写读操作互斥,写写操作互斥,读写锁提高了读多写少案例的并发性能。
读写锁实现高效缓存:
/** * 使用Lock的读写锁实现高效缓存,使用单例模式实现缓存对象的唯一性 * @author zsc * @datetime 2017年11月13日 下午3:27:26 */public class Cache implements Serializable {private static final long serialVersionUID = 1L;// 缓存对象private static Cache instance = null;// 缓存容器static Map<String, Object> cache = new HashMap<String, Object>();// 读写锁static ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();// 读锁static Lock readLock = rrwl.readLock();// 写锁static Lock writeLock = rrwl.writeLock();/** * 构造方法私有化,禁止调用构造方法生成缓存对象 */private Cache() {super();}/** * 单例模式,获取缓存对象 * @return */public static Cache getInstance() {if(null == instance) {synchronized (instance) {if(null == instance) {instance = new Cache();}}}return instance;}/** * 根据Key查询缓存 * @param key * @return */public Object get(String key) {try {readLock.lock();return cache.get(key);} catch (Exception e) {e.printStackTrace();} finally {readLock.unlock();}return null;}/** * 设置缓存 * @param key * @param value */public void set(String key, String value) {try {writeLock.lock();cache.put(key, value);} catch (Exception e) {e.printStackTrace();} finally {writeLock.unlock();}}/** * 移除指定Key的缓存,默认返回被移除的value,key不存在则返回null * @param key * @return */public Object remove(String key) {try {writeLock.lock();return cache.remove(key);} catch (Exception e) {e.printStackTrace();} finally {writeLock.unlock();}return null;}/** * 清除所有缓存 */public void clear() {try {writeLock.lock();cache.clear();} catch (Exception e) {e.printStackTrace();} finally {writeLock.unlock();}}}