现对《Java多线程编程核心技术》中讲述的ReentrantLock类的使用条目,作一下个人总结,内容如下:
一、ReentrantLock-可重入锁
1、实现同步:
private Lock lock = new ReentrantLock();
public void runMethod() {
lock.lock();
for (int i = 0; i < 5; i++) {
logger.info("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1)));
}
lock.unlock();
}
2、使用Condition实现等待、通知
Object类中的wait()方法相当于Condition类中的await()方法
Object类中的wait(long timeout)方法相当于Condition类中的await(long time,TimeUnit unit)方法
Object类中的notify()方法相当于Condition类中的signal()方法
Object类中的notifyAll()方法相当于Condition类中的signalAll()方法
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
// 使用多个不同的Condition对象,可单独唤醒部分指定线程
private Condition conditionA = lock.newCondition();
public void await() {
try {
lock.lock();
logger.info("--时间:{}--AA----", System.currentTimeMillis());
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
@Override
public void signal() {
try {
lock.lock();
logger.info("--时间:{}--signal--1--", System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
3、公平锁与非公平锁
锁Lock分为“公平锁“和”非公平锁“,公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,非公平锁是一种获取锁的抢占机制,是随机获得锁的,这种方式可能会造成某些线程一直拿不到锁
ReentrantLock unFairlock = new ReentrantLock(false)
4、其他方法
//查询当前线程保持此锁定的个数
int holdCount = lock.getHoldCount();
//返回正等待获取此锁定的线程估计数
int queueLength = lock.getQueueLength();
//返回等待与此锁定相关的给定条件Condition的线程计数
int waitQueueLength = lock.getWaitQueueLength(condition);
//判断是不是公平锁:默认情况下,ReentrantLock使用的是非公平锁
boolean isFair = lock.isFair();
//查询当前线程是否保持此锁定
boolean heldByCurrentThread = lock.isHeldByCurrentThread();
//查询此锁定是否由任意线程保持
boolean locked = lock.isLocked();
二、ReentrantReadWriteLock-读写锁
ReentrantLock具有完全互斥排他的效果,同一时间只有一个线程在执行ReentrantLock.lock()方法后面的任务。这样保证了实例变量的线程安全,但效率却是低下的。ReentrantReadWriteLock-读写锁有两个锁,一个是读操作的锁,称为共享锁,一个是写操作相关的锁,称为排他锁。多个Tread可以同时进行读取操作,但是同一时刻只允许一个Tread进行写入操作。
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
lock.readLock().lock();
lock.writeLock().lock();
lock.readLock().unlock();
lock.writeLock().unlock();