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

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. 23.Kubernetes中的CRI

    Kubernetes中的CRI 前言 Kubernetes 节点的底层由一个叫做容器运行时的软件进行支撑,它主要负责启停容器. Docker 是目前最广为人知的容器运行时软件,但是它并非唯一.在这几年 ...

  2. Netty+Spring Boot 加持,解锁高性能 Web 应用

    MiniTomcat(https://github.com/daichangya/MiniTomcat) 这个项目是一个基于Netty的Java Web服务器,它提供了从简单HTTP服务器到集成Spr ...

  3. 如何使用Python编写一个Lisp解释器

    原文出处: Peter Norvig   译文出处: jnjc(@jnjcc) 本文有两个目的: 一是讲述实现计算机语言解释器的通用方法,另外一点,着重展示如何使用Python来实现Lisp方言Sch ...

  4. AtCoder Beginner Contest 378

    Contest Link 还得加练. A & B & C & D 不具备任何思维含量. Submission A Submission B Submission C Submi ...

  5. Ubuntu下xrdp登陆故障解决方案

    故障描述: Ubuntu使用xrdp远程桌面运行一段时间后,出现登陆错误: xrdp_mm_process_login_response: login failed 原因分析: 远程桌面没有正确关闭所 ...

  6. Python 学习记录(1)

    前言 简单说明: 简单情况:主要记录学习Python的简单情况,包括代码与结果,以及关键注释 工具与来源: 以下代码与结果都可在JupyterLab上实现,更多情况可看Github 使用 NumPy ...

  7. ae基于面要素生成柱状图

    IFeatureLayer fl = axMapControl1.get_Layer(0) as IFeatureLayer; IGeoFeatureLayer pGeoFeatLyr = fl as ...

  8. uni-app Vue3项目引入Tailwind CSS

    前情 Tailwind CSS 是一个原子类 CSS 框架,它将基础的 CSS 全部拆分为原子级别,同时还补全各种浏览器模式前缀,兼容性也不错.它的工作原理是扫描所有 HTML 文件.JavaScri ...

  9. RHCL8无法使用yum install的解决方法

    ​报错如下: Updating Subscription Management repositories. Unable to read consumer identity This system i ...

  10. git 报错 error: bad signature 0x00000000 fatal: index file corrupt

    index file在 git 里面一般指的是 .git/index 这个文件.这个文件保存的是暂存区的信息(索引信息). 报错说明这个文件已经损坏了 直接删除这个文件,然后执行如下命令 git re ...