Lock接口
Lock接口在java.util.concurrent.locks包中,在jdk1.5之后才有。
Lock接口有6个方法:
void lock();
void lockInterruptibly() throws InterruptedException;
Condition newCondition();
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Lock接口有一个实现类ReentrantLock。reentrant中文意思是可重入的。可重入锁能够支持一个线程对资源的重复加锁,注意是同一个线程的重复加锁,不是多个线程的加锁。此外,可重入锁还支持公平的或者非公平的选择获取锁的线程。
其实synchronized关键字也是可重入的,支持同步代码块或者同步方法的嵌套。
ReentrantLock有3个静态内部类:Sync、NonfairSync、FairSync,具体如下:
java.util.concurrent.locks.ReentrantLock.Sync是继承AbstractQueuedSynchronizer(队列同步器,以下简称同步器)抽象类的抽象类,有一个抽象的void lock();方法。这里需要提醒下,AbstractQueuedSynchronizer虽然是抽象类,但是该类没有抽象方法,其实完全可以不定义成抽象类。
java.util.concurrent.locks.ReentrantLock.NonfairSync和java.util.concurrent.locks.ReentrantLock.FairSync都是Sync的子类,前者是非公平同步实现,后者是公平同步实现,这两个类均重写了Sync的lock()方法和AbstractQueuedSynchronizer的tryAcquire(int acquires)方法。ReentrantLock实例的lock()方法内部就是调用Sync实例的lock()方法,具体是NonfairSync实例还是FairSync实例,要看构造ReentrantLock实例时传的参数,如果传入的是true,则是公平可重入锁,如果传的是false,则是非公平可重入锁。无参构造出来的是非公平的。非公平可重入锁相对于公平可重入锁,效率高很多,TPS高很多,因为相对来说少了大量的线程切换。
ReentrantLock用法示例:


public class ReentrantLockTest extends Thread { public static ReentrantLock lock = new ReentrantLock(); public static int i = 0; public ReentrantLockTest(String name) { super.setName(name); } public static void main(String[] args) throws InterruptedException { ReentrantLockTest test1 = new ReentrantLockTest("thread1"); ReentrantLockTest test2 = new ReentrantLockTest("thread2"); test1.start(); test2.start(); test1.join(); test2.join(); System.out.println("main terminate"); } @Override public void run() { for (int j = 0; j < 10; j++) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } lock.lock(); try { System.out.println("lock=" + lock + ", name=" + this.getName() + " ,i=" + i); i++; } finally { lock.unlock(); } } } }
ReadWriteLock接口
synchronized锁和Lock都是排他锁,这些锁在同一时刻只允许一个线程访问。而读写锁ReadWriteLock在同一时刻可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相对于一般的排他锁有很大的提升。
ReadWriteLock接口只有两个方法:
Lock readLock();
Lock writeLock();
ReadWriteLock接口的实现类是ReentrantReadWriteLock。ReentrantReadWriteLock类有100个静态内部类:
java.util.concurrent.locks.ReentrantReadWriteLock.Sync:
java.util.concurrent.locks.ReentrantReadWriteLock.NonfairSync:
java.util.concurrent.locks.ReentrantReadWriteLock.FairSync:
java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock:
java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock: