一、例子
- 一段简单的使用ReentrantLock的例子
public class ReentrantLockMain {
static String workContent = null;
public static void main(String[] args) throws InterruptedException {
//new一个锁
Lock lock = new ReentrantLock();
//生成一个condition
Condition condition = lock.newCondition();
//开启子线程小T
new Thread(() -> {
lock.lock();
try {
String name = Thread.currentThread().getName();
System.out.println(name+":我获取到锁了,开始工作了");
if(workContent == null){
System.out.println(name+":M夫人还没布置工作啊,等等吧");
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+":收到M夫人的工作【"+ workContent +"】, 很快我就做完了");
}finally {
lock.unlock();
}
},"子线程小T").start();
Thread.sleep(1000);
System.out.println(">>>>>>>>>>>>>>>10秒后M夫人驾到<<<<<<<<<<<<<<");
Thread.sleep(10000);
//主线程获取锁
lock.lock();
try{
//获取到锁
System.out.println("M夫人:我获取到锁,开始布置任务");
workContent = "秘密任务:找bug";
System.out.println("M夫人:任务布置完成,叫【子线程小T】来做");
condition.signal();
}finally {
lock.unlock();
}
}
}
- 代码执行结果
子线程小T:我获取到锁了,开始工作了
子线程小T:M夫人还没布置工作啊,等等吧
>>>>>>>>>>>>>>>10秒后M夫人驾到<<<<<<<<<<<<<<
M夫人:我获取到锁,开始布置任务
M夫人:任务布置完成,叫【子线程小T】来做
子线程小T:收到M夫人的工作【秘密任务:找bug】, 很快我就做完了
二、 锁使用说明
- new ReentrantLock()
创建一个lock,在其内部其实是创建了一个NonfairSync对象赋值给锁的sync变量。此处为非公平锁。
- lock.newCondition()
创建一个Condition,在其内部实际为调用了sync的newCondition方法,而再内部实际为new ConditionObject()。(此处有知识点)
- lock.lock()
获取锁,为阻塞式的,此处非公平锁的话。(之后单说公平锁与非公平锁代码上实现的具体区别)
- condition.await()
比较像synchronized中使用wait,但是condition.await()比较灵活,一个锁可以设置多个condition
- condition.signal()
比较像synchronized中使用notify,同样,condition.signal()也可以是多个condition,比较灵活
- lock.unlock()
释放锁资源,此处使用的锁状态实际为占有锁的一个计数器,同时唤起下一等待线程(sync队列节点里记录了)