1、ReentrantLock类
JDK1.5之后新增的类,使用效果上和synchronized相同,但是功能更强大,例如,嗅探功能、多路分支通知功能等等
ReentrantLock结合Condition实现等待/通知 其等价于wait()/notify()
区别:
wait() notify()/notifyAll():进行通知时,被通知的线程是由JVM随机选择的,而ReentrantLock结合Condition可以实现“选择性通知”
condition:具有更好的灵活性,可在一个lock对象中创建多个condition即‘对象监视器’,线程可注册在指定的condition,从而可以进行有选择性的通知。而synchronized相当于lock对象中只有一个condition对象,所有线程注册在一个对象上,线程开始notifyAll(),通知所以watting线程,没有选择性。
代码描述:
public class TestReentrantLock {
private Lock lock = new ReentrantLock();
public Condition c1 = lock.newCondition();
public Condition c2 = lock.newCondition();
public void awaitA(){
lock.lock();
try {
System.out.println("A方法进入等待!");
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
public void awaitB(){
lock.lock();
try {
System.out.println("B方法进入等待!");
c2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
public void signalAll_A(){
lock.lock();
System.out.println("单独唤醒A方法!");
c1.signalAll();
lock.unlock();
}
public void signalAll_B(){
lock.lock();
System.out.println("单独唤醒B方法!");
c2.signalAll();
lock.unlock();
}
}
2、ReentrantReadWriteLock类
读写锁描述:
现实场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了
特性:
(1)公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。
(2)重进入:读锁和写锁都支持线程重进入。
(3)锁降级:遵循获取写锁、获取读锁再释放写锁的次序,写锁能够降级成为读锁。
互斥性:
‘读写’、‘写写’ 互斥 ; ‘读读’是异步非互斥的