Java线程的通信
当需要多个线程共同完成一件任务,而且需要有规律的执行,那么多个线程之间需要一定的通信机制,可以协调他们的工作,以此实现多线程共同操作一份数据。
1 等待唤醒机制
这是一种线程间的协作机制,与争夺锁的竞争机制相对应,当一个线程满足某个条件时,就进入等待状态( wait/wait(m) ),等到其他线程执行完指定的代码后,再将其唤醒,或者可以指定时间,到时间了自动唤醒,有多个线程等待时,如果有需要,可以notifyAll()唤醒所有等待的线程,wait/notify就是一种线程间的协助机制。
wait()
- 作用:使当前线程等待,直到其他线程调用相同对象的
notify()或notifyAll()方法,或者线程被中断。 - 使用场景:当一个线程需要等待某个条件发生时,比如资源可用、状态改变等。
- 条件:调用
wait()方法时,当前线程必须持有该对象的监视器锁(synchronized),否则会抛出IllegalMonitorStateException异常。
synchronized (sharedObject) {
while (!condition) {
sharedObject.wait(); // 释放锁并等待
}
// 条件满足后的操作
}
notify()
- 作用:唤醒在该对象上等待的一个线程。如果有多个线程在等待,则随机选择一个线程唤醒。
- 使用场景:在某个条件被满足时,通知一个等待的线程继续执行。
synchronized (sharedObject) {
// 修改条件
sharedObject.notify(); // 唤醒一个等待线程
}
notifyAll()
- 作用:唤醒在该对象上等待的所有线程。
- 使用场景:当条件变化可能影响所有等待线程时,使用
notifyAll()确保所有线程都有机会重新检查条件。
synchronized (sharedObject) {
// 修改条件
sharedObject.notifyAll(); // 唤醒所有等待线程
}
2 例子
2.1 两个线程共同卖票,一人一张
public class Ticket {
public static void main(String[] args) {
TicketTask t1 = new TicketTask();
TicketTask t2 = new TicketTask();
t1.start();
t2.start();
}
static class TicketTask extends Thread {
static int ticket = 200;
static final Object lock = new Object();
@Override
public void run() {
while (true) {
synchronized (lock) {
lock.notifyAll();
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() +" " + ticket);
ticket--;
}
else {
break;
}
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
}
2.2 两个线程共同交替从1加到100
public class TestAdd {
static int i = 0;
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
synchronized (this){
this.notify();
if (i < 100) {
System.out.println(Thread.currentThread().getName() + "---" + ++i);
}
else {
break;
}
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
};
new Thread(runnable).start();
new Thread(runnable).start();
}
}
Java线程的通信的更多相关文章
- Java线程间通信-回调的实现方式
Java线程间通信-回调的实现方式 Java线程间通信是非常复杂的问题的.线程间通信问题本质上是如何将与线程相关的变量或者对象传递给别的线程,从而实现交互. 比如举一个简单例子,有一个多线程的 ...
- Java线程之间通信
用多线程的目的:更好的利用CPU的资源.因为所有的多线程代码都可以用单线程来实现. 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程. 并行:多个CPU实例或者多台机器同时执行一段处理逻辑, ...
- Java线程间通信之wait/notify
Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式.我们来看下相关定义: w ...
- java线程间通信:一个小Demo完全搞懂
版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.从一个小Demo说起 上篇我们聊到了Java多线程的同步 ...
- Java——线程间通信
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- 说说Java线程间通信
序言 正文 [一] Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在 ...
- 说说 Java 线程间通信
序言 正文 一.Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在一个 ...
- java线程间通信1--简单实例
线程通信 一.线程间通信的条件 1.两个以上的线程访问同一块内存 2.线程同步,关键字 synchronized 二.线程间通信主要涉及的方法 wait(); ----> 用于阻塞进程 noti ...
- Java——线程间通信问题
wait和sleep区别: 1.wait可以指定时间可以不指定. sleep必须指定时间. 2.在同步时,对cpu的执行权和锁的处理不同. wait:释放执行权,释放锁. ...
- java 线程之间通信以及notify与notifyAll区别。
jvm多个线程间的通信是通过 线程的锁.条件语句.以及wait().notify()/notifyAll组成. 下面来实现一个启用多个线程来循环的输出两个不同的语句. package com.app. ...
随机推荐
- K8s之运行时containerd安装和使用
一.containerd 1. 前生今世 很久以前,Docker 强势崛起,以"镜像"这个大招席卷全球,对其他容器技术进行致命的降维打击,使其毫无招架之力,就连 Google 也不 ...
- 超级干货!Air780E的串口通信分享
猛然发现,Air780E的串口通信还没分享,难怪已经有小伙伴提出了要求! 那我们来讲解低功耗4G模组Air780E的串口通信的基本用法,小伙伴们,学起来吧! 一.硬件准备 780E开发板一套 ...
- python的迭代器和生成器?
python中的迭代器和生成器都是用来处理数据序列的. 迭代器 迭代器是一个可以记住遍历位置的对象,使用iter()创建一个迭代器,使用next()方法依次返回迭代器中的每一个元素,如果数组里面的数据 ...
- Spring AOP实现原理与CGLIB应用
AOP(Aspect Orient Programming),也就是面向方面编程,作为面向对象编程的一种补充,专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在 Java EE 应用 ...
- golang之异步队列Asynq
Asynq[1]是一个Go实现的分布式任务队列和异步处理库,基于redis,类似Ruby的sidekiq[2]和Python的celery[3].Go生态类似的还有machinery[4]和gowor ...
- 在window 使用 docker 安装redis 踩坑记
1. 安装REDIS 在安装的时候,使用 docker pull redis 就可以了. 但是 实际上 发现镜像居然拉不下来. 修改了一下 docker 镜像. 配置如下: "registr ...
- 从Delphi到Lazarus——安装最新版的Lazarus
0.前言 在这篇文章里将会介绍以下内容: 下载最新版的Lazarus安装程序 安装Lazarus 安装整合IDE界面的软件包 编译运行你的第一个测试程序 结束语 1.下载最新版的Lazarus安装程序 ...
- mysql将公司数据随机挂在部门身上
1.创建示例数据 CREATE TABLE department_table ( company_code VARCHAR(10) COMMENT '公司编码', company_name VARCH ...
- 【转载】 利用p6spy拦截并查看数据库执行操作
https://blog.csdn.net/fanxiaobin577328725/article/details/71601760 一.简介 项目首 页:http://p6spy.github.io ...
- DevNow x Notion
前言 Notion 应该是目前用户量比较大的一个在线笔记软件,它的文档系统也非常完善,支持多种文档格式,如 Markdown.富文本.表格.公式等. 早期我也用过一段时间,后来有点不习惯,就换到了 O ...