Lock与synchronized的区别


对比项
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();
		}
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值