Java中的线程通信的几种方式

article/2025/9/24 17:47:37

Java中的线程间通信是指不同线程之间相互协作,以完成一些复杂的任务或实现某些功能的过程。线程间通信主要包括两个方面:线程之间的互斥和同步,以及线程之间的数据共享和通信。Java提供了多种方式来实现线程间通信,本文将介绍Java中的几种常见的线程间通信方式。

在这里插入图片描述

synchronized关键字

synchronized是Java中最基本的实现线程之间互斥和同步的机制。synchronized可以用来修饰方法或代码块,用来确保在同一时间只有一个线程可以执行被修饰的代码块或方法。通过synchronized关键字,我们可以实现线程之间的互斥和同步。以下是一个使用synchronized实现线程同步的例子:

public class SynchronizedDemo {private int count = 0;public synchronized void increment() {count++;}public synchronized int getCount() {return count;}
}

在这个例子中,我们使用synchronized关键字修饰了increment()和getCount()方法,以确保在同一时间只有一个线程可以执行这两个方法。这样就可以避免不同线程之间对count变量的并发访问和修改,从而实现线程之间的同步和互斥。

wait()和notify()方法

wait()和notify()方法是Java中实现线程间通信的另一种方式。wait()方法可以使线程进入等待状态,直到其他线程调用notify()方法来通知该线程继续执行。notify()方法可以唤醒一个正在等待的线程,使其继续执行。以下是一个使用wait()和notify()方法实现线程通信的例子:

public class WaitNotifyDemo {public static void main(String[] args) {Message message = new Message("Hello World");// 创建发送线程Thread senderThread = new Thread(new Sender(message));// 创建接收线程Thread receiverThread = new Thread(new Receiver(message));// 启动发送线程和接收线程senderThread.start();receiverThread.start();}
}class Message {private String content;public Message(String content) {this.content = content;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}
}class Sender implements Runnable {private Message message;public Sender(Message message) {this.message = message;}public void run() {String[] messages = {"message1", "message2", "message3"};for (String message : messages) {// 发送消息this.message.setContent(message);try {// 等待接收线程接收消息Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}class Receiver implements Runnable {private Message message;public Receiver(Message message) {this.message = message;}public void run() {for (int i = 0; i < 3; i++) {// 等待发送线程发送消息synchronized (message) {try {message.wait();} catch (InterruptedException e) {e.printStackTrace();}}// 接收并处理消息System.out.println("Received message: " + message.getContent());}}
}

在这个例子中,我们使用wait()和notify()方法来实现线程间的通信。Sender线程通过设置message对象的content属性来发送消息,然后等待1秒钟,让Receiver线程有足够的时间来接收消息。Receiver线程通过wait()方法来等待Sender线程发送消息,直到接收到消息后再进行处理。

CountDownLatch类

CountDownLatch类是Java中提供的一种线程同步工具,它可以用来控制一个或多个线程等待其他线程完成任务后再继续执行。CountDownLatch类的工作原理是通过一个计数器来实现的,当计数器的值减为0时,等待该计数器的线程将被唤醒。以下是一个使用CountDownLatch类实现线程同步的例子:

public class CountDownLatchDemo {public static void main(String[] args) {final int N = 3;final CountDownLatch latch = new CountDownLatch(N);// 创建N个线程for (int i = 0; i < N; i++) {new Thread() {public void run() {try {// 线程执行任务Thread.sleep((long) (Math.random() * 10000));System.out.println(Thread.currentThread().getName() + " completed task");// 计数器减1latch.countDown();} catch (InterruptedException e) {e.printStackTrace();}}}.start();}try {// 等待所有线程完成任务latch.await();System.out.println("All threads completed their tasks.");} catch (InterruptedException e) {e.printStackTrace();}}
}

在这个例子中,我们使用CountDownLatch类来实现线程之间的同步。我们创建了N个线程,并让它们执行任务,每个线程执行任务后都会将计数器减1,直到所有线程都执行完任务后,主线程才会继续执行。

Semaphore类

Semaphore类是Java中提供的一种线程同步工具,它可以用来控制同时访问某个资源的线程数量。Semaphore类的工作原理是通过一个计数器来实现的,当每个线程访问该资源时,计数器就减1,当计数器的值为0时,其他线程就不能再访问该资源。以下是一个使用Semaphore类实现线程间通信的例子:

public class SemaphoreDemo {public static void main(String[] args) {final int N = 10;final Semaphore semaphore = new Semaphore(3);// 创建N个线程for (int i = 0; i < N; i++) {new Thread() {public void run() {try {// 请求许可证semaphore.acquire();System.out.println(Thread.currentThread().getName() + " acquired permit");// 线程执行任务Thread.sleep((long) (Math.random() * 10000));// 释放许可证semaphore.release();System.out.println(Thread.currentThread().getName() + " released permit");} catch (InterruptedException e) {e.printStackTrace();}}}.start();}}
}

在这个例子中,我们使用Semaphore类来控制同时访问某个资源的线程数量。我们创建了N个线程,并让它们请求许可证,如果许可证的数量已经达到了3个,那么其他线程就需要等待,直到有线程释放许可证后才能继续执行。

BlockingQueue类

BlockingQueue类是Java中提供的一种线程安全的队列,它可以用来实现线程间的数据共享和通信。BlockingQueue类的工作原理是,当队列为空时,从队列中取数据的操作会被阻塞,直到队列中有数据;当队列已满时,向队列中添加数据的操作会被阻塞,直到队列中有空间。以下是一个使用BlockingQueue类实现线程间通信的例子:

public class BlockingQueueDemo {public static void main(String[] args) {final int N = 10;final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(N);// 创建发送线程Thread senderThread = new Thread(new Sender(queue));// 创建接收线程Thread receiverThread = new Thread(new Receiver(queue));// 启动发送线程和接收线程senderThread.start();receiverThread.start();}
}class Sender implements Runnable {private BlockingQueue<String> queue;public Sender(BlockingQueue<String> queue) {this.queue = queue;}public void run() {String[] messages = {"message1", "message2", "message3"};for (String message : messages){try {// 添加消息到队列中queue.put(message);System.out.println("Sent message: " + message);} catch (InterruptedException e) {e.printStackTrace();}}}}class Receiver implements Runnable {private BlockingQueue<String> queue;public Receiver(BlockingQueue<String> queue) {this.queue = queue;}public void run() {while (true) {try {// 从队列中取出消息String message = queue.take();System.out.println("Received message: " + message);} catch (InterruptedException e) {e.printStackTrace();}}}
}

在这个例子中,我们使用BlockingQueue类来实现线程间的通信。Sender线程通过调用queue.put()方法将消息添加到队列中,Receiver线程通过调用queue.take()方法从队列中取出消息。如果队列为空,Receiver线程会阻塞,直到有消息被添加到队列中。同样地,如果队列已满,Sender线程也会阻塞,直到有空间可用。

总结

Java中提供了多种方式来实现线程间通信,其中最常见的方式包括synchronized关键字、wait()和notify()方法、CountDownLatch类、Semaphore类和BlockingQueue类。这些方式都可以用来实现线程之间的互斥、同步、数据共享和通信。选择哪种方式取决于具体的应用场景和需求。在使用这些方式时,需要注意线程安全和死锁等问题,以确保程序的正确性和健壮性。


http://chatgpt.dhexx.cn/article/GUS9Namy.shtml

相关文章

创建线程的四种方式 线程通信

文章目录 1.1 创建线程1.1.1 创建线程的四种方式1.1.2 Thread类与Runnable接口的比较1.1.3 Callable、Future与FutureTask 1.2 线程组和线程优先级1.3 Java线程的状态及主要转化方法1.4 Java线程间的通信1.4.1 等待/通知机制1.4.2 信号量1.4.3 管道 1.1 创建线程 1.1.1 创建线…

【多线程间几种通信方式】

一、使用 volatile 关键字 基于 volatile 关键字来实现线程间相互通信是使用共享内存的思想。大致意思就是多个线程同时监听一个变量&#xff0c;当这个变量发生变化的时候 &#xff0c;线程能够感知并执行相应的业务。这也是最简单的一种实现方式 代码案例 package com.han…

线程之间的通信方式

前言 我只是个搬运工&#xff0c;尊重原作者的劳动成果&#xff0c;本文来源下列文章链接&#xff1a; https://zhuanlan.zhihu.com/p/129374075 https://blog.csdn.net/jisuanji12306/article/details/86363390 线程之间为什么要通信&#xff1f; 通信的目的是为了更好的协…

Java线程间的通信方式

文章目录 线程间通信的定义一、等待—通知&#xff08;1&#xff09;等待—通知机制的相关方法&#xff1a;&#xff08;2&#xff09;注意事项&#xff1a;&#xff08;4&#xff09;notify()方法的核心原理&#xff08;5&#xff09;等待—通知机制的经典范式&#xff08;6&a…

线程间实现通信的几种方式

目录 线程通信相关概述提出问题方式一&#xff1a;使用Object类的wait() 和 notify() 方法方式二&#xff1a;Lock 接口中的 newContition() 方法返回 Condition 对象&#xff0c;Condition 类也可以实现等待/通知模式方法三&#xff1a;使用 volatile 关键字方法四&#xff1a…

线程间的通信方式

对共享数据进行更改的时候&#xff0c;先到主内存中拷贝一份到本地内存中&#xff0c;然后进行数据的更改&#xff0c;再重新将数据刷到主内存&#xff0c;这中间的过程&#xff0c;其他线程是看不到的。 1、为什么需要线程通信 线程是操作系统调度的最小单位&#xff0c;有自…

进程和线程的几种通信方式

进程之间通信的几种方式 1. 管道&#xff1a;是内核里面的一串缓存 管道传输的数据是单向的&#xff0c;若相互进行通信的话&#xff0c;需要进行创建两个管道才行的。 2. 消息队列&#xff1a; 例如&#xff0c;A进程给B进程发送消息&#xff0c;A进程把数据放在对应的消息队…

线程的几种通信方式

目录 一、Object的wait()、notify()、notifyAll()方法 二、Condition的await()、signal()、signalAll()方法 三、CountDownLatch 四、CyclicBarrier 五、Semaphore 线程间的通信方式常用的有如下几种&#xff1a; Object的wait()、notify()、notifyAll()方法&#xff1b; …

线程间的通信方法

线程间的通信方法 1. 线程通信简介 一般而言&#xff0c;在一个应用程序&#xff08;即进程&#xff09;中&#xff0c;一个线程往往不是孤立存在的&#xff0c;常常需要和其它线程通信&#xff0c;以执行特定的任务。如主线程和次线程&#xff0c;次线程与次线程&#xff0c…

Matlab基本操作函数 abs函数

分享一下我老师大神的人工智能教程&#xff01;零基础&#xff0c;通俗易懂&#xff01;http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章。分享知识&#xff0c;造福人民&#xff0c;实现我们中华民族伟大复兴&#xff01; 1、abs函数&#xff1a;数值的绝对值和复数…

MATLAB中FFT的整理

作为一个资深的健忘症患者&#xff0c;需要把每次用都忘记的FFT问题进行整理。 FFT可将信号从时域转换到频域。 首先是一些简单常识&#xff1a; 采样周期&#xff1a;两次采样之间的时间间隔。 采样频率&#xff1a;1/采样周期。每秒采样的点数。&#xff08;注意&#xff1a…

matlab中abs函数,matlababs是什么意思 是是是什么意思

matlababs是什么意思 是是是什么意思以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! matlab 中的abs函数什么意思 编程知识 matlab中的abs(x)是去绝对值的函数 例如:x=-1.23 abs(x) ans 1.23 以上即是取了-1.23…

Matlab 用法

MATLAB基础&#xff1a; 清除命令 clc 清空命令行的命令 clf 清除当前figure中的内容 clear 清除工作区变量 close all 关闭所有图形窗口 清除命令通常放在代码最前方&#xff0c;避免其他变量或代码的干扰 变量命名规则 ①以英文字母开头&#xff0c;可包含英文字母、…

abs 三种功能及代码详解 matlab函数

1.abs函数功能 求实数的绝对值、复数的模、字符串的ASCII值 2.基本用法 abs(x)函数是对数组元素进行绝对值处理的函数。 函数的定义域包括复数。 对于复数xab*i&#xff0c;有abs(x)sqrt(a2b2)。 3.代码 clc; clear all;a -7; b 12i; abs(a…

android 屏幕坐标总结

android 屏幕坐标好多个&#xff0c;有时候傻傻分不清楚&#xff0c;经常记错&#xff0c;然后只能一个个试。尴尬&#xff5e;&#xff5e; 把它们总结下来&#xff0c;以备不时之需嘿嘿。 一、视图坐标 最外面一层是屏幕&#xff0c;左上角是坐标原点&#xff0c;向右向…

【Unity3D】世界坐标与屏幕坐标

Unity3D由于是在三维世界中编程&#xff0c;而最终的结果是需要反馈到肉眼所示的2D屏幕之上的。这就产生了一种比较需要考虑的问题&#xff0c;尤其在一些涉及屏幕与Unity3D的3D世界交互的情况。网络上对于这方面的文字&#xff0c;大部分罗列了许许多多文字与代码或者API&…

Unity世界坐标转换屏幕坐标(测试)

下面展示一下上一篇说的两种实现方式打包文件在不同分辨率下的效果 1.WorldToScreenPoint 1920 * 1080 800 * 600 2.WorldToViewportPoint 1920 * 1080 800 * 600 总结 可以看到四种情况全部都显示正确&#xff0c;我们再看一下原来的代码 public Vector3 GetScreenPositio…

Unity 屏幕坐标转UI坐标

1&#xff1a;屏幕坐标转UI坐标 首先我们来明确下三个坐标概念&#xff1a; 世界坐标&#xff1a;指的是Transform组件的position字段 UI坐标&#xff1a;指的是RectTransform组件的anchoredPosition字段 屏幕坐标&#xff1a;指的是屏幕空间的坐标 (也可以说是相机空间的坐…

经纬度转换成屏幕坐标

学期projet总结&#xff1a; 当把点的数据和线的数据读进来之后&#xff0c;为了画出地图还有最重要的一步就是把实际的经纬度转换成屏幕像素点的坐标。在找老师讨论之前&#xff0c;我在网上查资料&#xff0c;找到了下边链接的文章&#xff0c;并按照这个方法画出了地图。 …

Unity-世界坐标与屏幕坐标

transform.position.x和transform.position.y的值含义是世界坐标。 世界坐标与屏幕坐标有时一样&#xff0c;有时不同&#xff0c;这和Canvas的渲染模式有关。 Canvas共有三种渲染模式 Screen Space - Overlay (此模式UGUI层一直在最上面&#xff0c;其他例如粒子等物体一直…