java 公平锁和非公平锁区别

  • Post author:
  • Post category:java




公平锁和非公平锁的区别

  1. 公平锁 指在分配锁前检查是否有线程在排队等待获取该锁,优先将锁分配给排队时间最长的线程
  2. 非公平锁 指在分配锁时不考虑线程排队等待的情况,直接尝试获取锁,在获取不到锁时再排到队尾等待

    因为公平锁需要在多核的情况下维护一个锁线程等待队列,基于该队列进行锁的分配,因此效率比非公平锁低很多,java中的synchronized时非公平锁,ReentranLock默认的lock方法采用的时非公平锁。



读写锁:ReadWriteLock

  1. 在Java中通过Lock接口及对象可以方便的为对象加锁和释放锁,但是这种锁不区分读写,叫做普通锁。为了提供性能,Java提供了读写锁,读写锁分为读锁和写锁,在写的地方使用写锁,在没有写的地方,读时无阻塞的。
  2. 如果系统要求共享数据可以同事支持很多线程并发读,但不能支持很多线程并发写,那么使用读锁能很大程度地提高效率,如果系统要求共享数据在同一时刻只能有一个线程在写,再写的过程中不能读取共享数据,则需要使用写锁。
public class SeafCache{
	private final Map<String,Object> cache= new HashMap<String,Object>();
	private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
	private final Lock readLock =rwlock.readLock();//step1:定义读锁
	private final Lock writeLock =rwlock.writeLock();//step2:定义写锁

	public Object get(String key){
	readLock.lock();
	try{
	return cache.get(key);
	}finally{
	readLock.unLock();
	}
	}
//step4:再写数据时加写锁
public Object put(String key,Object value){
	writeLock.lock();
	try{
	return cache.put(key,value);
	}finally{
	writeLock.lock();
	}
}

}




共享锁和独占锁

  1. 独占锁:也叫互斥锁,每次只允许一个线程持有该锁,ReentrantLock为独占锁的实现
  2. 共享锁:允许多个线程同时获取该锁,并发访问共享资源。ReentrantReadWriteLock中的读锁为共享锁的实现。

    ReentrantReadWriteLock的加锁和解锁操作最终都调用内部类Sync提供的方法。Sync对象通过继承AQS(Abstract Queued Synchronizer)进行实现。AQS的内部类Node定义了两个常量SHARED和EXCLUSIVE,费别标识AQS队列中等待线程的锁获取模式。

    独占锁是一种悲观的枷锁策略,同一时刻只允许一个读线程读取锁资源,限制了读操作的并发性;因为并发读线程并不会影像数据的一致性,因此共享锁采用了乐观的枷锁策略,允许多个执行读操作的线程同时访问共享资源。



版权声明:本文为yitian881112原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。