欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Lock与synchronized的区别

程序员文章站 2024-01-08 08:34:40
...

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

上一篇:

下一篇: