我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么在java中实现线程间通信

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么在java中实现线程间通信

这篇文章将为大家详细讲解有关怎么在java中实现线程间通信,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

线程间通信:由于多线程共享地址空间和数据空间,所以多个线程间的通信是一个线程的数据可以直接提供给其他线程使用,而不必通过操作系统(也就是内核的调度)。

进程间的通信则不同,它的数据空间的独立性决定了它的通信相对比较复杂,需要通过操作系统。以前进程间的通信只能是单机版的,现在操作系统都继承了基于套接字(socket)的进程间的通信机制。这样进程间的通信就不局限于单台计算机了,实现了网络通信。线程通信主要分为以下几个部分,下面通过生活中图书馆借书的例子简单讲解以下:

通过共享对象通信

加入图书馆只有一本《java并发编程实战》,小A早上的时候把这本书给借走了,然后下午小B去图书馆去找这本书,这时候小A和小B是两个线程,《java并发编程实战》就是共享对象(类似于多线程中的全局变量的资源),小B发现这本书已经被借走了,所以就回去等了几天,几天后,小B又去图书馆发现这本书被还回来了,就把书借走了,这就是通过共享对象进行通信。

忙等待

由于快要BAT实习生招聘了,所以小B非常想看这本书,所以小B就每隔一个小时(while循环)就去看看这本书有没有被还回来了,这样虽然比较耗费处理器资源,但是只要书一旦被还回来,小B就可以马上知道。

wait() notify() notifyAll()

由于图书馆隔着宿舍比较近,所以小B发现每隔一个小时就去图书馆身体有点吃不消,不过很快,学校的图书馆系统增加了短信提醒功能(notify()),所以小B可以一边睡觉一边等短信。

丢失的信号

图书馆系统是这么设计的,当有一本书被还回来的时候,就会给等待者发短信,但是短信只能发送一次,如果没有等待者,短信也会发出(只不过这个时候没有没有接受者),问题出现了,因为短信只会发一次,当书被还回来的时候,没有人等待借书,他会发一条空短信,但是之后有等待借此本书的同学永远也不会再收到短信,导致这些同学会无休止的等待。为了解决这个问题,我们要进入等待状态的时候先打电话问问图书馆阿姨是否需要继续等待。

假唤醒

图书馆系统有一个bug,会是不是给用户发送错误短信,我们很听话,收到短信就会去图书馆借书,但是到达图书馆后发现书根本就没有被还回来,然后接着做其他的事情。

线程间的通信方式

#锁机制:包括互斥锁、条件变量、读写锁

*互斥锁提供了以排他方式防止数据结构被并发修改的方法。

*读写锁允许多个线程同时读共享数据,而对写操作是互斥的。

*条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。

#信号量机制(Semaphore):包括无名线程信号量和命名线程信号量

#信号机制(Signal):类似进程间的信号处理

线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。

我觉得我对线程通信的理解还是不够彻底,下面分享几段代码,帮助理解:

①同步

这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信。

参考示例:

public class MyObject {synchronized public void methodA() {//do something....}synchronized public void methodB() {//do some other thing}}public class ThreadA extends Thread {private MyObject object;//省略构造方法@Override public void run() {super.run();object.methodA();}}public class ThreadB extends Thread {private MyObject object;//省略构造方法@Override public void run() {super.run();object.methodB();}}public class Run {public static void main(String[] args) {MyObject object = new MyObject();//线程A与线程B 持有的是同一个对象:objectThreadA a = new ThreadA(object);ThreadB b = new ThreadB(object);a.start();b.start();}}

由于线程A和线程B持有同一个MyObject类的对象object,尽管这两个线程需要调用不同的方法,但是它们是同步执行的,比如:线程B需要等待线程A执行完了methodA()方法之后,它才能执行methodB()方法。这样,线程A和线程B就实现了通信。

这种方式,本质上就是“共享内存”式的通信。多个线程需要访问同一个共享变量,谁拿到了锁(获得了访问权限),谁就可以执行。

②while轮询的方式

代码如下:

import java.util.ArrayList;import java.util.List;public class MyList {private List<String> list = new ArrayList<String>();public void add() {list.add("elements");}public int size() {return list.size();}}import mylist.MyList;public class ThreadA extends Thread {private MyList list;public ThreadA(MyList list) {super();this.list = list;}@Override public void run() {try {for (int i = 0; i < 10; i++) {list.add();System.out.println("添加了" + (i + 1) + "个元素");Thread.sleep(1000);}}catch (InterruptedException e) {e.printStackTrace();}}}import mylist.MyList;public class ThreadB extends Thread {private MyList list;public ThreadB(MyList list) {super();this.list = list;}@Override public void run() {try {while (true) {if (list.size() == 5) {System.out.println("==5, 线程b准备退出了");throw new InterruptedException();}}}catch (InterruptedException e) {e.printStackTrace();}}}import mylist.MyList;import extthread.ThreadA;import extthread.ThreadB;public class Test {public static void main(String[] args) {MyList service = new MyList();ThreadA a = new ThreadA(service);a.setName("A");a.start();ThreadB b = new ThreadB(service);b.setName("B");b.start();}}

在这种方式下,线程A不断地改变条件,线程ThreadB不停地通过while语句检测这个条件(list.size()==5)是否成立 ,从而实现了线程间的通信。但是这种方式会浪费CPU资源。之所以说它浪费资源,是因为JVM调度器将CPU交给线程B执行时,它没做啥“有用”的工作,只是在不断地测试 某个条件是否成立。就类似于现实生活中,某个人一直看着手机屏幕是否有电话来了,而不是: 在干别的事情,当有电话来时,响铃通知TA电话来了。关于线程的轮询的影响

③wait/notify机制

代码如下:

import java.util.ArrayList;import java.util.List;public class MyList {private static List<String> list = new ArrayList<String>();public static void add() {list.add("anyString");}public static int size() {return list.size();}}public class ThreadA extends Thread {private Object lock;public ThreadA(Object lock) {super();this.lock = lock;}@Override public void run() {try {synchronized (lock) {if (MyList.size() != 5) {System.out.println("wait begin "    + System.currentTimeMillis());lock.wait();System.out.println("wait end "    + System.currentTimeMillis());}}}catch (InterruptedException e) {e.printStackTrace();}}}public class ThreadB extends Thread {private Object lock;public ThreadB(Object lock) {super();this.lock = lock;}@Override public void run() {try {synchronized (lock) {for (int i = 0; i < 10; i++) {MyList.add();if (MyList.size() == 5) {lock.notify();System.out.println("已经发出了通知");}System.out.println("添加了" + (i + 1) + "个元素!");Thread.sleep(1000);}}}catch (InterruptedException e) {e.printStackTrace();}}}public class Run {public static void main(String[] args) {try {Object lock = new Object();ThreadA a = new ThreadA(lock);a.start();Thread.sleep(50);ThreadB b = new ThreadB(lock);b.start();}catch (InterruptedException e) {e.printStackTrace();}}}

线程A要等待某个条件满足时(list.size()==5),才执行操作。线程B则向list中添加元素,改变list的size。

A,B之间如何通信的呢?也就是说,线程A如何知道list.size()已经为5了呢?

这里用到了Object类的wait()和notify()方法。

当条件未满足时(list.size()!=5),线程A调用wait()放弃CPU,并进入阻塞状态。---不像②while轮询那样占用CPU

当条件满足时,线程B调用notify()通知线程A,所谓通知线程A,就是唤醒线程A,并让它进入可运行状态。

这种方式的一个好处就是CPU的利用率提高了。

但是也有一些缺点:比如,线程B先执行,一下子添加了5个元素并调用了notify()发送了通知,而此时线程A还执行;当线程A执行并调用wait()时,那它永远就不可能被唤醒了。因为,线程B已经发了通知了,以后不再发通知了。这说明:通知过早,会打乱程序的执行逻辑。

④管道通信就是使用java.io.PipedInputStream和java.io.PipedOutputStream进行通信

具体就不介绍了。分布式系统中说的两种通信机制:共享内存机制和消息通信机制。感觉前面的①中的synchronized关键字和②中的while轮询“属于”共享内存机制,由于是轮询的条件使用了volatile关键字修饰时,这就表示它们通过判断这个“共享的条件变量“是否改变了,来实现进程间的交流。

关于怎么在java中实现线程间通信就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么在java中实现线程间通信

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么在java中实现线程间通信

这篇文章将为大家详细讲解有关怎么在java中实现线程间通信,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。线程间通信:由于多线程共享地址空间和数据空间,所以多个线程间的通信是一个线程的数据可以
2023-05-30

怎么在java中实现线程通信

本篇文章给大家分享的是有关怎么在java中实现线程通信,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应
2023-06-14

Java中怎么实现线程间通信与信号量

Java中怎么实现线程间通信与信号量,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1.信号量Semaphore先说说Semaphore,Semaphore可以控制某个资源可
2023-05-30

Java中怎么实现多线程通信

Java中怎么实现多线程通信,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。概述多线程通信问题,也就是生产者与消费者问题生产者和消费者为两个线程,两个线程在运行过程中交替睡眠,生
2023-06-20

Java中怎么使用wait和notify实现线程间的通信

这篇“Java中怎么使用wait和notify实现线程间的通信”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中怎么使
2023-06-30

Java怎么使用wait或notify实现线程间通信

这篇文章主要介绍“Java怎么使用wait或notify实现线程间通信”,在日常操作中,相信很多人在Java怎么使用wait或notify实现线程间通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎
2023-07-04

Java中线程之间的通信是如何实现的

这篇文章将为大家详细讲解有关Java中线程之间的通信是如何实现的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。正常情况下,每个子线程完成各自的任务就可以结束了。不过有的时候,我们希望多个线程
2023-05-31

Java中的多线程如何实现线程通信

这篇文章将为大家详细讲解有关Java中的多线程如何实现线程通信,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java多线程中线程间的通信一、使用while方式来实现线程之间的通信packag
2023-05-31

Java通过wait()和notifyAll()方法实现线程间通信

本文实例为大家分享了Java实现线程间通信的具体代码,供大家参考,具体内容如下Java代码(使用了2个内部类):package Threads;import java.util.LinkedList;/** * Created by Fra
2023-05-31

Java如何实现线程通信

今天小编给大家分享一下Java如何实现线程通信的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。什么是线程通信、如何实现?所谓线
2023-06-30

在Java中,如何实现多线程之间的同步与通信?(Java多线程编程时,应如何确保线程间的同步与有效通信?)

本文详细介绍了Java多线程编程中的同步和通信机制。为了实现同步,可以使用synchronized关键字、Lock接口或Semaphore。同步确保多个线程在访问共享资源时保持一致性。对于通信,共享内存、消息队列和管道等机制允许线程共享数据和协调任务。文中还提供了代码示例、最佳实践和问题的预防策略。通过这些机制,开发者可以创建同步且有效的Java多线程应用程序。
在Java中,如何实现多线程之间的同步与通信?(Java多线程编程时,应如何确保线程间的同步与有效通信?)
2024-04-02

android线程间怎么通信

在Android中,线程间通信可以通过以下几种方式实现:1. Handler:可以通过Handler对象在不同的线程之间发送消息。每个线程可以拥有自己的Handler对象,通过Handler对象可以发送消息到其他线程的消息队列中,然后其他线
2023-08-19

Java如何使用wait/notify实现线程间通信

本文小编为大家详细介绍“Java如何使用wait/notify实现线程间通信”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java如何使用wait/notify实现线程间通信”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习
2023-07-04

Android中怎么实现进程间通信

这篇文章给大家介绍Android中怎么实现进程间通信,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。由于android系统中应用程序之间不能共享内存。因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些。进程间通
2023-06-04

Java编程中实现Condition控制线程通信

java中控制线程通信的方法1.传统的方式:利用synchronized关键字来保证同步,结合wait(),notify(),notifyAll()控制线程通信。不灵活。2.利用Condition控制线程通信,灵活。3.利用管道pipe进行
2023-05-30

怎么在Android中使用AIDL实现进程间通信

怎么在Android中使用AIDL实现进程间通信?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、概述AIDL 意思即 Android Interface Definiti
2023-05-30

java中多线程怎么进行通信

今天就跟大家聊聊有关java中多线程怎么进行通信,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、概要线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录