当需要多个线程共同完成一件任务,而且需要有规律的执行,那么多个线程之间需要一定的通信机制,可以协调他们的工作,以此实现多线程共同操作一份数据。

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线程的通信的更多相关文章

  1. Java线程间通信-回调的实现方式

    Java线程间通信-回调的实现方式   Java线程间通信是非常复杂的问题的.线程间通信问题本质上是如何将与线程相关的变量或者对象传递给别的线程,从而实现交互.   比如举一个简单例子,有一个多线程的 ...

  2. Java线程之间通信

    用多线程的目的:更好的利用CPU的资源.因为所有的多线程代码都可以用单线程来实现. 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程. 并行:多个CPU实例或者多台机器同时执行一段处理逻辑, ...

  3. Java线程间通信之wait/notify

    Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式.我们来看下相关定义: w ...

  4. java线程间通信:一个小Demo完全搞懂

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.从一个小Demo说起 上篇我们聊到了Java多线程的同步 ...

  5. Java——线程间通信

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  6. 说说Java线程间通信

    序言 正文 [一] Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在 ...

  7. 说说 Java 线程间通信

    序言 正文 一.Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在一个 ...

  8. java线程间通信1--简单实例

    线程通信 一.线程间通信的条件 1.两个以上的线程访问同一块内存 2.线程同步,关键字 synchronized 二.线程间通信主要涉及的方法 wait(); ----> 用于阻塞进程 noti ...

  9. Java——线程间通信问题

     wait和sleep区别: 1.wait可以指定时间可以不指定.     sleep必须指定时间. 2.在同步时,对cpu的执行权和锁的处理不同.     wait:释放执行权,释放锁.     ...

  10. java 线程之间通信以及notify与notifyAll区别。

    jvm多个线程间的通信是通过 线程的锁.条件语句.以及wait().notify()/notifyAll组成. 下面来实现一个启用多个线程来循环的输出两个不同的语句. package com.app. ...

随机推荐

  1. 13.Kubernetes核心技术Ingress

    Kubernetes核心技术Ingress 前言 原来我们需要将端口号对外暴露,通过 ip + 端口号就可以进行访问 原来是使用Service中的NodePort来实现 在每个节点上都会启动端口 在访 ...

  2. python的迭代器和生成器?

    python中的迭代器和生成器都是用来处理数据序列的. 迭代器 迭代器是一个可以记住遍历位置的对象,使用iter()创建一个迭代器,使用next()方法依次返回迭代器中的每一个元素,如果数组里面的数据 ...

  3. 霍夫丁(Hoeffding)不等式证明

    马尔可夫不等式 结论 对于任意非负随机变量$X$,$\forall \epsilon>0$,有: $\displaystyle P(X\ge\epsilon)\le\frac{E(X)}{\ep ...

  4. JDBC性能小贴

    本文由 ImportNew - 刘志军 翻译自 javarevisited.如需转载本文,请先参见文章末尾处的转载要求. 本文收集了一些用于提升JDBC性能的方法.Java应用或者JavaEE Web ...

  5. noip2024

    NOIP2024 游记 考试之前一直有很多话想在游记里说,但考完后又不知道该说些什么.这六个月的集训时光仿佛像一场梦一般. 怒砍\([60, 100] + 0 + 0 + 0\) 作为一个只学了不到一 ...

  6. Javascript 异步处理

    1.传统异步处理 ES6之前使用回调进行处理,示例代码: //创建一个异步返回 双倍数值 的函数 function asyncDouble(num,cb){ // 创建标识,表示该异步处理是否完成 v ...

  7. S2P销讯通-SFE人才对企业管理层至关重要

    SFE这一概念,最初由外资企业引入,如今已逐渐被内资企业所采纳并融入其组织结构中,不少企业正积极构建这一部门. 1 我们观察到,近两年企业内对于SFE部门所需的人才需求急剧上升.这一部门,在外资企业中 ...

  8. 腾讯云 COS 多 AZ 存储保证服务高可用性

    腾讯云 COS 的多 AZ 存储架构能够为用户数据提供数据中心级别的容灾能力.多 AZ 存储将客户数据分散存储在城市中多个不同的数据中心,当某个数据中心因为自然灾害.断电等极端情况导致整体故障时,多 ...

  9. 实用干货分享(5)- Hive存储格式及压缩算法测试比对分析

    ​ ​编辑 Hive文件存储格式及优缺点 textfile 默认的文件格式,行存储.建表时不指定存储格式即为textfile,导入数据时把数据文件拷贝至hdfs不进行处理. 优点:最简单的数据格式,便 ...

  10. Microsoft Excel 成为合适的编程语言

    https://thenewstack.io/microsoft-excel-becomes-a-programming-language/ 微软的研究人员相信,由于引入了一项名为 LAMBDA 的新 ...