上一篇文章中讲到我们使用synchronized去实现线程安全的通信,今天我们来看一下使用Lock锁的时候能否进行线程之间的通信呢?
首先先简单介绍一下本次用到的方法和类
本篇文章仅简单讲解一下如何去使用,具体的源码和细节后续会另开一篇文章去讲解!
Condition
这是一个在Java5之后出现的工具类,可以实现类似于wait与notify一样的等待通知功能,并且支持多路与指定通知,更加灵活
我们在使用notify进行通知时是由JVM随机调度的,而我们使用condition中的通知功能则可以自己指定去通知哪个线程
但是我们在使用condition的方法之前,我们需要先获取Lock锁
await
await是condition类中的一个方法,作用与wait相似,将一个线程进入阻塞状态,其实会进入到conditon的队列当中,之后可以选择性去唤醒
signal
signal是conidtion类中的一个方法,作用与notify相似,但是其实signal并不是真正去唤醒线程
// 注意(要调用lock.unlock或再次调用await,内部都会执行release方法将Node解除阻塞)
代码
/**
* @author LFDMW
* @date 2020-11-15 1:04
*/
public class MyLockWait implements Runnable {
private MyLockService service;
public MyLockWait(MyLockService service) {
this.service = service;
}
@Override
public void run() {
service.waitService();
}
}
class MyLockService {
private Lock lock = new ReentrantLock();
// 创建一个condition对象需要调用lock的newConfition方法
private Condition condition = lock.newCondition();
public void waitService() {
lock.lock();
try {
System.out.println("线程进入等待状态");
// 调用await使线程进入condition的等待队列中
condition.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("线程解锁了");
}
public void notice() {
lock.lock();
try {
// 从condition等待队列中找出一个线程来唤醒
// 注意(要调用lock.unlock或再次调用await,内部都会执行release方法将Node解除阻塞)
condition.signal();
} finally {
lock.unlock();
}
}
}
class MyLockWaitTest {
public static void main(String[] args) throws InterruptedException {
MyLockService service = new MyLockService();
MyLockWait myLockWait = new MyLockWait(service);
new Thread(myLockWait).start();
Thread.sleep(3000);
service.notice();
}
}
// TODO:关于await及signal的细节较多,后续会单独再开一篇去详细的研究源码和原理,届时会贴出链接在这,感谢观看!