Java并发编程——线程间通信

news2025/2/23 19:45:54

线程间通信

    • 一、volatile 关键字
    • 二、等待/通知机制
    • 三、管道通信
    • 四、Thread.join

一、volatile 关键字

为什么volatile关键字可以?因为之前说过了,此关键字能保证变量的可见性,也就是说变量一旦被修改,立马能被其他线程所感知

例子如下:

private static volatile boolean flag=true;

private static void setFlag(){
    flag=false;
}
public static void main(String[] args) {
    new Thread(()->{
        System.out.println("还没变");
        while (flag){
            // flag不改变 就一直死循环直至发现值改变
        }
        System.out.println("我感知到变化了");
    }).start();
    try {
        //等待1s才执行下一个线程
        Thread.sleep(1000); 
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    new Thread(()->{
        setFlag();
        System.out.println("我修改了");
    }).start();
}

二、等待/通知机制

相关方法为:

  • notify():通知一个在对象上等待的线程,使其从wait()方法返回,返回的前提是该线程获得了锁
  • notifyAll():通知所有在该对象上等待的线程
  • wait():调用该方法进入waiting状态并会释放锁,只有被其他线程通知或者中断才返回
  • wait(long):超时等待一段时间,到时间了还没通知就返回
  • wait(long,int):增加了超时时间单位的控制

例子如下:

public static Object flag=true;

public static void main(String[] args) throws InterruptedException {
    new Thread(()->{
        synchronized (flag){
            System.out.println("线程1:进入等待");
            try {
                flag.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程1:从等待中归来");
        }
    }).start();
   Thread.sleep(1000);
   new Thread(()->{
       synchronized (flag){
           System.out.println("线程2:上面那个线程调用wait后会释放锁,所以到我啦");
           flag.notify();
           System.out.println("线程2:我把它唤醒了,但是它需要等我执行完释放掉锁才会返回");
       }
   }).start();
}

结果:

在这里插入图片描述

注意:这个使用需要配合synchronized 使用

三、管道通信

管道输入流/输出流主要包括如下4个具体实现:

  • PipedInputStream
  • PipedOutputStream
  • PipedReader
  • PipedWriter

前两种面向字节,后两种面向字符

例子如下:

public static void main(String[] args) throws InterruptedException, IOException {
        // 读为接收
        PipedReader in = new PipedReader();
        // 写为输出
        PipedWriter out = new PipedWriter();
        // 将管道输入和输出连接起来
        out.connect(in);
        new Thread(() -> {
            int receive = 0;
            while (true) {
                try {
                    if (((receive = in.read()) != -1)) {
                        System.out.println("接收到了:"+receive);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(()->{
            try {
                // 这里输入,给那边接收
                out.write(11111);
                // 死循环防止输入端结束 管道断裂
                while (true){}
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

    }

结果:

在这里插入图片描述

四、Thread.join

这个是干嘛呢?就是等待线程结束

假设线程A执行了threadB.join()语句,其含义是:当前线程A等待线程B执行结束后才返回。说白了就是等待其他线程执行后才执行

例子如下:

public static void main(String[] args) throws InterruptedException, IOException {
      System.out.println("主线程:我开始执行啦");
      Thread threadB = new Thread(() -> {
          System.out.println("线程B:我开始执行啦");
          System.out.println("线程B:我要睡会儿");
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          System.out.println("线程B:我睡醒执行完了");
      });
      threadB.start();
      System.out.println("主线程:我等待线程B执行完我再执行");
      threadB.join();
      System.out.println("主线程:线程B执行完了,到我执行了");
  }

结果:主线程一定是最后才执行完的

在这里插入图片描述

但是如果把join注释掉,那么线程B一定是最后执行完的:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

拓端tecdat|R语言代做泰坦尼克号随机森林模型案例数据分析

全文链接:http://tecdat.cn/?p4281 原文出处:拓端数据部落公众号 视频:从决策树到随机森林:R语言信用卡违约分析信贷数据实例 从决策树到随机森林:R语言信用卡违约分析信贷数据实例,时长10:11 如果我们对…

Linux:环境变量

基本概念 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。 环境变量通常具有某些特殊用途,通常具有全局特性,可以被子进程继承下去 常见的环境变量 PATH : 指定命令的搜索路径 HOME : 指定用户的主工作目录(即用户登陆到Linux系统中…

[Linux]----文件操作(复习C语言+文件描述符)

文章目录前言一、基础概念二、回顾C语言2.1 对文件进行写操作2.2 追加写文件2.3 读文件2.4 简易cat功能总结stdin&stdout&stderr打开文件的方式三、系统文件I/O接口介绍open介绍使用open接口closewriteread四、文件描述符先验证0,1,2就是标准的IO标准输入流标准输出流标…

基于寄生-捕食算法的函数寻优算法

文章目录一、理论基础1、寄生-捕食算法(1)初始化(2)筑巢阶段(鸟窝)(3)寄生阶段(乌鸦-布谷鸟)(4)捕食阶段(乌鸦-猫)2、PPA算法伪代码二、仿真实验与结果分析三、参考文献一、理论基础…

QCC51XX---QACT用户指南

更新记录链接:QCC51XX---系统学习目录_嵌入式学习_force的博客-CSDN博客 QACT安装包不要放在有中文路径下,否则—直会安装报错。适用V7,V7.1 V7.2版本 打开QACT. 打开QACT. 点击 connection configuration 进去之后 点击1,然后点2,选择kalaccess.dll文件, workspace …

【C++】vector的模拟实现不会怎么办?看过来

🌈欢迎来到C专栏~~vector的模拟实现 (꒪ꇴ꒪(꒪ꇴ꒪ )🐣,我是Scort🎓🌍博客主页:张小姐的猫~江湖背景快上车🚘,握好方向盘跟我有一起打天下嘞!送给自己的一句鸡汤🤔&…

MySQL是如何保证主从一致的

一:什么是binlog Binary log(二进制日志),简称Binlog。 Binlog是记录所以数据表结构变更以及表数据修改的二进制日志,不会记录select和show这类操作。Binlog是以事件形式记录,还包括语句所执行的消耗时间。Binlog是MySql Server自…

0082 时间复杂度,冒泡排序

/* * 排序也称排序算法(Sort Algorithm) * 排序是将一组数据,依指定的顺序进行排列的过程。 * * 排序分类 * 1.内部排序:将需要处理的所有数据都加载到内存存储器中进行排序(使用内存) * 插…

Keil MDK的sct分散加载文件详解

sct 分散加载文件简介 MDK 生成一个以工程名命名的后缀为 *.sct 的分散加载文件 (Linker Control File,scatter loading),链接器根据该文件的配置分配各个节区地址,生成分散加载代码,因此我们通过修改该文件可以定制具体节区的存…

Spring源码:Spring源码阅读环境搭建

本篇内容包括:Mac 环境下 gradle 的安装和配置、源码克隆、新建测试类,测试Spring源码 等内容! 第一步:Mac 环境下 gradle 的安装和配置 1、下载安装包 # 到 GitHub 的 Spring 仓库选定 Spring 版本,查看对应版本 Sp…

Linux项目自动化构建工具make/makefile

1.背景 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计其数,其按类型,功能,模块分别放在若干目录中,makefile定义了一系列的规则来制定,那些文件需要先编译&a…

C艹笔记--面向对象程序设计

文章目录类与对象简介类与结构的区别定义成员函数继承继承小总结[C中::和:, .和->的作用和区别](https://zhuanlan.zhihu.com/p/165992745)符号::和:的作用和区别:::一般用来表示继承符号.和->的作用和区别#include#include""和#include…

STM32入门——基本 GPIO 的输出控制

文章目录1 什么是 GPIO ?1.1 GPIO 简介1.2 GPIO 硬件解析1.2.1 保护二极管1.2.2 P-MOS、N-MOS 管1.2.3 数据输入输出寄存器1.2.4 复用功能输出1.2.5 模拟输入输出1.3 GPIO 的工作模式1.3.1 输入模式 (模拟/浮空/上拉/下拉)1.3.2 输出模式 (推挽/开漏)1.3.3 复用功能…

基于Nodejs+vue开发实现酒店管理系统

作者简介:Java、前端、Pythone开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发、毕业设计开发、面试技术整理、最新技术分享 项目编号:BS-QD-KS-002 一,项目简介 本项目使用纯前端技…

mysql约束

文章目录mysql约束非空约束唯一性约束主键约束使用自增列:AUTO_INCREMENTFOREIGN KEY约束CHECK约束mysql约束 为什么需要约束?为了保证数据的完整性什么叫约束?对表中字段的限制约束的分类: 角度1:约束的字段个数&…

吴峰光杀进 Linux 内核

【编者按】吴峰光,Linux 内核守护者,学生时代被同学戏称为“老神仙”,两耳不闻窗外事,一心只搞 Linux。吴峰光的 Linux 内核之路,是天赋、兴趣、耐心、坚持的综合,这从一个补丁前后迭代了 16 个版本后还进行…

【初识Netty使用Netty实现简单的客户端与服务端的通信操作Netty框架中一些重要的类以及方法的解析】

一.Netty是什么? Netty 由 Trustin Lee(韩国,Line 公司)2004 年开发 本质:网络应用程序框架 实现:异步、事件驱动 特性:高性能、可维护、快速开发 用途:开发服务器和客户端 Netty的性能很高&#xff0…

字符串匹配算法(BF、KMP)

目录 1、暴力匹配(BF)算法 2、KMP算法 1、暴力匹配(BF)算法 BF算法,即暴力(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T 的第一个字符进行匹配&a…

【树莓派不吃灰】配置samba,文件夹目录配置在闲置U盘,实现局域网文件共享

目录1. 前言2. 安装 Samba2.1 安装samba 和 samba-common-bin2.2 配置/etc/samba/smb.conf文件2.3 配置登录账号和密码2.4 重启 samba 服务2.5 回到windows,就可以在网络当中发现共享的文件夹3. 在Windows上挂载smb的共享目录3.1 打开windows的smb功能3.2 添加网络映…

Java --- springMVC实现RESTFul案例

一、使用springMVC实现RESTFul小案例 1.1、项目目录图&#xff1a; 1.2、代码实现&#xff1a; pom.xml文件&#xff1a; <packaging>war</packaging><!--添加依赖--><dependencies><!--SpringMVC--><dependency><groupId>org.spr…