可重入锁,作用是使线程安全。对比于sychronized
,它能具有以下特点
更加灵活
可重入锁可以理解为锁的一个标识。该标识具备计数器功能。标识的初始值为0,表示当前锁没有被任何线程持有。每次线程获得一个可重入锁的时候,该锁的计数器就被加1。每次一个线程释放该所的时候,该锁的计数器就减1。前提是:当前线程已经获得了该锁,是在线程的内部出现再次获取锁的场景
tryLock()方
法实现。此方法仅在调用时锁为空闲状态才获取该锁。如果锁可用,则获取锁,并立即返回值true。如果锁不可用,则此方法将立即返回值false。of invocation.
*/
lock.tryLock()
```
当使用内部锁时,一旦开始请求,锁就不能停止了,所以内部锁给实现具有时限的活动带来了风险。为了解决这一问题,可以使用定时锁。当具有时限的活
动调用了阻塞方法,定时锁能够在时间预算内设定相应的超时。如果活动在期待的时间内没能获得结果,定时锁能使程序提前返回。可定时的锁获取模式,由tryLock(long, TimeUnit)
方法实现。
可中断的锁获取操作允许在可取消的活动中使用。lockInterruptibly()方法能够使你获得锁的时候响应中断。
ReentrantLock提供了synchronized类似的功能和内存语义。(提供了对资源加锁的功能)
当使用lock的时候,不能使用 CountDownLatch 来进行倒计时操作,会报出IllegalMonitorStateException
异常。因为当线程被唤醒后,资源信息与lock对象已经不是一一对应的关系,可能出现资源被A线程加锁,但是线程B尝试去解锁。
/**
* @author: n
* @date: 2019/5/13:上午11:41
*/
public class ReentrentLockTest implements Runnable{
private ReentrentLockDemo demo = new ReentrentLockDemo(10);
private static ReentrantLock lock = new ReentrantLock();
static CountDownLatch begin = new CountDownLatch(1);
static CountDownLatch end = new CountDownLatch(10);
@Override
public void run() {
try {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + "-->调用run方法被阻塞跳出run线程回到main方法线程");
//
begin.await();
//lock.tryLock();
int num = demo.splice();
System.out.println(threadName + "--->" + num);
end.countDown();
} catch (Exception e) {
e.printStackTrace();
}finally {
//lock.unlock();
}
}
public static void main(String[] args) throws Exception {
ReentrentLockTest test = new ReentrentLockTest();
for (int i = 0; i < 10; i++) {
Thread t = new Thread(test);
/**
* 进入到run方法,run方法被begin阻塞。run方法退出,重新回到main中。从而完成对所有线程的初始化
*
*
*/
// System.out.println(“”);
t.start();
}
// 调用countDown。所有线程被唤醒,开始执行run方法
begin.countDown();
end.await();
System.out.println("end");
}
}
原文:https://www.cnblogs.com/KevinStark/p/10857578.html