Java菜鸟,初学多线程,使用的教材是《疯狂java讲义(第四版)》。有理解不到位的地方,欢迎批评指正~
(文章末尾有整个笔记的pdf版本和md版本)
Java 多线程笔记(1)——线程简介
Java 多线程笔记(2)——创建/启动线程
Java 多线程笔记(3)——线程的生命周期
Java 多线程笔记(4)——控制线程
Java 多线程笔记(5)——线程同步
Java 多线程笔记(6)——线程通信
6. 线程通信
保证线程协调运行的机制。使线程间可以互相发送信号,也可以使线程等待其他线程的信号。
6.1 传统线程通信
Java中,使用Object类的wait()、notify()和notifyAll()三个方法实现线程通信。这三个方法必须由同步监视器调用(针对同步代码块和同步方法)。
- 同步方法中,同步监视器是this,所以可以在同步方法中直接调用这三个方法
- 同步代码块中,同步监视器是括号里的对象,所以要用该对象调用这三个方法
三个方法的功能解释:
- wait():使当前线程等待,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来换唤醒该线程。
- notify():唤醒在此同步监视器上等待的单个线程。如果有多个在等待,则任意选择一个唤醒。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。
- notifyAll():唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。
6.2 使用Condition控制线程通信
如果程序使用Lock对象保证同步,则不能使用wait()、notify()或notifyAll()方法进行线程通信。
Java提供了Condition类来针对这种情况下的线程通信。Condition实例可由Lock对象的newCondition()方法获得。与传统线程通信相似,Condition类提供了三个方法:
- await():与wait()类似,使当前线程等待,直到其他线程调用该Condition的signal()方法或signalAll()方法来唤醒该线程。
- signal():唤醒在次Lock对象上等待的单个线程。如果有多个线程在该Lock对象上等待,则任意选择一个唤醒。只有当前线程放弃对该Lock对象的锁定后,才可以执行被唤醒的线程。
- signalAll():唤醒在此Lock对象上等待的所有线程。只有当前线程放弃对该Lock对象的锁定后,才可以执行被唤醒的线程。
//使用newCondition()方法创建Condition实例
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
...
lock.lock();
try {
if (...) {
condition.await(); //使当前线程等待
} else {
condition.signalAll(); //唤醒在该Lock对象上等待的所有线程
}
} finally {
lock.unlock();
}
...
6.3 使用阻塞队列(BlockingQueue)控制线程通信
BlockingQueue是Queue的子接口。当生产者线程试图向BlockingQueue中放入元素时,如果该队列已满,则该线程被阻塞;当消费者线程试图从BlockingQueue中取出元素时,如果该队列已空,则该线程被阻塞。
BlockingQueue中支持阻塞的方法为:put()和take()
使程序的两个或多个线程交替向BlockingQueue中放入、取出元素,可以很好的控制线程通信。
完整笔记下载:
pdf版链接:https://pan.baidu.com/s/1AxAo3ZLwf5EwUV6i6yWp8Q
提取码:6jom
md文件链接:https://pan.baidu.com/s/1tX0HCJteEVwCoXC0Hkw68Q
提取码:99t1