Java线程之间的协作
当多个线程可以一起工作去解决某个问题时,如果某些部分必须在其它部分之前完成,那么就需要对线程进行协调。
join()
在线程中调用另一个线程的 join() 方法,会将当前线程挂起,而不是忙等待,直到目标线程结束。
对于以下代码,虽然 b 线程先启动,但是因为在 b 线程中调用了 a 线程的 join() 方法,b 线程会等待 a 线程结束才继续执行,因此最后能够保证 a 线程的输出先于 b 线程的输出。
public class JoinExample {private class A extends Thread {@Overridepublic void run() {System.out.println("A");}}private class B extends Thread {private A a;B(A a) {this.a = a;}@Overridepublic void run() {try {a.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("B");}}public void test() {A a = new A();B b = new B(a);b.start();a.start();}
}
public static void main(String[] args) {JoinExample example = new JoinExample();example.test();
}
输出
A
B
wait() notify() notifyAll()
调用 wait() 使得线程等待某个条件满足,线程在等待时会被挂起,当其他线程的运行使得这个条件满足时,其它线程会调用 notify() 或者 notifyAll() 来唤醒挂起的线程。
它们都属于 Object 的一部分,而不属于 Thread。
只能用在同步方法或者同步控制块中使用,否则会在运行时抛出 IllegalMonitorStateException。
使用 wait() 挂起期间,线程会释放锁。这是因为,如果没有释放锁,那么其它线程就无法进入对象的同步方法或者同步控制块中,那么就无法执行 notify() 或者 notifyAll() 来唤醒挂起的线程,造成死锁。
public class WaitNotifyExample {public synchronized void before() {System.out.println("before");notifyAll();}public synchronized void after() {try {wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("after");}
}
public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();WaitNotifyExample example = new WaitNotifyExample();executorService.execute(() -> example.after());executorService.execute(() -> example.before());
}
输出
before
after
wait() 和 sleep() 的区别
- wait() 是 Object 的方法,而 sleep() 是 Thread 的静态方法;
- wait() 会释放锁,sleep() 不会。
await() signal() signalAll()
java.util.concurrent 类库中提供了 Condition 类来实现线程之间的协调,可以在 Condition 上调用 await() 方法使线程等待,其它线程调用 signal() 或 signalAll() 方法唤醒等待的线程。
相比于 wait() 这种等待方式,await() 可以指定等待的条件,因此更加灵活。
使用 Lock 来获取一个 Condition 对象。
public class AwaitSignalExample {private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();public void before() {lock.lock();try {System.out.println("before");condition.signalAll();} finally {lock.unlock();}}public void after() {lock.lock();try {condition.await();System.out.println("after");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}
}
public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();AwaitSignalExample example = new AwaitSignalExample();executorService.execute(() -> example.after());executorService.execute(() -> example.before());
}
输出
before
after
Java线程之间的协作相关推荐
- 线程的状态转换、sleep()、wait()、yeild()、终止线程的方法、线程之间的协作(join()、wait() notify() notifyAll()、await() signal() )
1.线程的状态转换 1.1 新建(New) 创建后尚未启动 1.2 可运行(Runnable) 可能正在运行,也可能正在等待 CPU 时间片. 包含了操作系统线程状态中的 Running 和 Read ...
- Java 线程之间通信
目录 概念 原理 实现 1. 第一种解法,包含多种小的不同实现方式,但一个共同点就是靠一个共享变量来做控制: a. 利用最基本的synchronized.notify.wait: b. 利用Lock和 ...
- Java线程之间通信
用多线程的目的:更好的利用CPU的资源.因为所有的多线程代码都可以用单线程来实现. 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程. 并行:多个CPU实例或者多台机器同时执行一段处理逻辑, ...
- 多线程:线程之间的协作(join、wait、notify、notifyAll、await、signal、signalAll)
当多个线程可以一起工作去解决某个问题时,如果某些部分必须在其它部分之前完成,那么就需要对线程进行协调. join() 在线程中调用另一个线程的 join() 方法,会将当前线程挂起,而不是忙等待,直到 ...
- 黑马程序员————java线程之间的通信
------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...
- JAVA线程之间的通信
原理 线程的通信可以被定义为:当多个线程共同操作共享的资源时,线程间通过某种方式互相告知自己的状态,以避免无效的资源争夺.线程间通信的方式可以有很多种:等待-通知.共享内存.管道流.每种方式用不同的方 ...
- Java线程详解(9)-并发协作
Java线程:并发协作-生产者消费者模型 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应 ...
- java线程详解_Java线程详解
程序.进程.线程的概念程序(program):是为完成特定任务.用某种语言编写的一组指令的集合.即指一段静态的代码,静态对象. 进程(process):是程序的一次执行过程,或是正在运行的一个程序.动 ...
- java线程-从生产者和消费者模型说起
今天学习了经典的生产者和消费者模型,引起了对java线程等知识的一系列的思考. 在平时的编程中,经常遇到一个线程要产生数据,而另一个线程要处理产生出来的数据,这其实就是生产者和消费者的关系.生产者在产 ...
最新文章
- 如何快速评估16S rRNA基因引物的覆盖率及特异性
- 【JVM调优】JVM指令集大全
- 深入分析Flex [Bindable] (总结)
- php提交表单并发送邮件,php提交表单发送邮件的方法
- NMEA码详解【转】
- java 正负随机_如何产生一个随机的[0, n)范围内的Short值
- 第4届(2020)大学生集成电路创新创业大赛赛题分类
- stm32系统时钟配置,标准库v3.5
- Tomcat8安装步骤-win10-64位系统
- 如何将png图像转换成jpg格式呢?
- 国民生产总值饼状图_预期寿命和国内生产总值
- 计算机实践ps折扇,用PS打造一把水墨画折扇的教程
- STM32F401的RCC时钟配置
- 1980-2018年中国及世界各国实际利率数据
- 视频摘要和视频浓缩的区别
- WORD中如何删除掉某几页的页眉和页脚
- SSL/TLS会话的流量分析
- 2021-04-05 c++程序设计原理与实践持续学习笔记:第三章对象、类型和值。
- 常用查找法(C语言)
- ENC28J60学习笔记——第2部分