在另一篇文章中Java的synchronized同步介绍了使用synchronized实现同步的特性,Java也可以使用Lock实现同步.本文主要介绍了使用Lock类来实现同步,并进行synchronized和Lock之间的比较.
ReentrantLock是一个类,而synchronized是关键字,ReentrantLock实现了Lock接口.
public class ReentrantLock implements Lock, java.io.Serializable
把解锁操作放在finally块中是必要的,这保证了锁一定会被释放掉,否则将会造成死锁.
ReentrantLock lock = new ReentrantLock(); lock.lock(); try { } finally { lock.unlock(); }
和synchronized一样,Lock锁是可重入的.线程可以重复获得已经持有的锁,锁保持一个持有计数器来跟踪对lock的嵌套调用.
如下的例子,此时线程1可以访问method2(),因为锁是可重入的.但是不能访问method3(),因为持有的是不同的锁.
ReentrantLock lock = new ReentrantLock(); ReentrantLock lock1 = new ReentrantLock(); //method1,锁为lock 正在被线程1访问 public void method1(){ lock.lock(); try { } finally { lock.unlock(); } } //method2,锁为lock public void method2(){ lock.lock(); try { } finally { lock.unlock(); } } //method3,锁为lock3 正在被线程2访问 public void method3(){ lock1.lock(); try { } finally { lock.unlock(); } }
ReentrantLock有一个构造器,为true是创建的是公平锁,ReentrantLock的空参构造器创建的是非公平锁.
public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
ReentrantLock是使用一个队列来管理公平锁,利用队列的先进先出特性来实现,哪个线程先等待锁,如果当前锁被释放,那么先等待的线程就会先获得锁,
如果是非公平锁那么获得锁的线程是随机的,这个方式有可能造成某些线程拿不到锁,因此是非公平的.
由于要使用队列来管理,因此公平锁相对来讲是效率比较低的.
转载请标明出处:Java的Lock同步
文章来源: Java的Lock同步