Java多线程中线程间的通信实例详解
发布时间 - 2026-01-11 00:54:28 点击率:次Java多线程中线程间的通信

一、使用while方式来实现线程之间的通信
package com.ietree.multithread.sync;
import java.util.ArrayList;
import java.util.List;
public class MyList {
private volatile static List list = new ArrayList();
public void add() {
list.add("apple");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final MyList list1 = new MyList();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
list1.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
if (list1.size() == 5) {
System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + " list size = 5 线程停止..");
throw new RuntimeException();
}
}
}
}, "t2");
t1.start();
t2.start();
}
}
程序输出:
当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. Exception in thread "t2" 当前线程收到通知:t2 list size = 5 线程停止.. java.lang.RuntimeException at com.ietree.multithread.sync.MyList$2.run(MyList.java:43) at java.lang.Thread.run(Unknown Source) 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素..
理解:线程Thread2不停地通过while语句检测这个条件(list.size()==5)是否成立 ,从而实现了线程间的通信。但是这种方式会浪费CPU资源。
二、wait notfiy 方法实现多线程中线程之间的通信
使用这种方式实现线程通信需要注意:wait和notify必须配合synchronized关键字使用,wait方法释放锁,notify方法不释放锁。并且在这个例子中必须是Thread2先执行才可以。
package com.ietree.multithread.sync;
import java.util.ArrayList;
import java.util.List;
public class ListAdd3 {
private volatile static List list = new ArrayList();
public void add() {
list.add("apple");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final ListAdd2 list2 = new ListAdd2();
// 1 实例化出来一个 lock
// 当使用wait 和 notify 的时候 , 一定要配合着synchronized关键字去使用
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
synchronized (lock) {
for (int i = 0; i < 10; i++) {
list2.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
if (list2.size() == 5) {
System.out.println("已经发出通知..");
//不释放锁,遇到size=5时还是继续执行
lock.notify();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
if (list2.size() != 5) {
try {
//释放锁,让其他线程执行
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("当前线程:" + Thread.currentThread().getName() + "收到通知线程停止..");
throw new RuntimeException();
}
}
}, "t2");
t2.start();
t1.start();
}
}
程序输出:
当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 已经发出通知.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t2收到通知线程停止.. Exception in thread "t2" java.lang.RuntimeException at com.ietree.multithread.sync.ListAdd3$2.run(ListAdd3.java:59) at java.lang.Thread.run(Unknown Source)
三、使用CountDownLatch类来实现多线程中线程之间的实时通信
package com.ietree.multithread.sync;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class ListAdd2 {
private volatile static List list = new ArrayList();
public void add() {
list.add("apple");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final ListAdd2 list2 = new ListAdd2();
final CountDownLatch countDownLatch = new CountDownLatch(1);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
list2.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
if (list2.size() == 5) {
System.out.println("已经发出通知..");
countDownLatch.countDown();
}
}
// }
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
if (list2.size() != 5) {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("当前线程:" + Thread.currentThread().getName() + "收到通知线程停止..");
throw new RuntimeException();
}
}, "t2");
t2.start();
t1.start();
}
}
程序输出:
当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 已经发出通知.. Exception in thread "t2" 当前线程:t1添加了一个元素.. 当前线程:t2收到通知线程停止.. java.lang.RuntimeException at com.ietree.multithread.sync.ListAdd2$2.run(ListAdd2.java:56) at java.lang.Thread.run(Unknown Source) 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素.. 当前线程:t1添加了一个元素..
四、使用多线程模拟一个队列
package com.ietree.multithread.sync;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class MyQueue {
// 1、定义一个盛装元素集合
private LinkedList<Object> list = new LinkedList<Object>();
// 2、定义一个计数器
private AtomicInteger count = new AtomicInteger();
// 3、指定上限和下限
private final int minSize = 0;
private final int maxSize;
// 4、构造方法初始化大小
public MyQueue(int size) {
this.maxSize = size;
}
// 5、初始化一个对象用于加锁
private Object lock = new Object();
// put(anObject): 把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断,直到BlockingQueue里面有空间再继续.
public void put(Object obj) {
synchronized (lock) {
if (count.get() == this.maxSize) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 1、加入元素
list.add(obj);
// 2、计数器累加
count.incrementAndGet();
// 3、通知(唤醒)另外一个线程
lock.notify();
System.out.println("新加入的元素为:" + obj);
}
}
// take: 取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入.
public Object take() {
Object ret = null;
synchronized (lock) {
while (count.get() == this.minSize) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 1、做移除元素操作
ret = list.removeFirst();
// 2、计数器作递减操作
count.decrementAndGet();
// 3、唤醒另外一个操作
lock.notify();
}
return ret;
}
// 获取长度
public int getSize() {
return this.count.get();
}
public static void main(String[] args) {
final MyQueue mq = new MyQueue(5);
mq.put("a");
mq.put("b");
mq.put("c");
mq.put("d");
mq.put("e");
System.out.println("当前容器的长度:" + mq.getSize());
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
mq.put("f");
mq.put("g");
}
}, "t1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Object o1 = mq.take();
System.out.println("移除的元素为:" + o1);
Object o2 = mq.take();
System.out.println("移除的元素为:" + o2);
}
}, "t2");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
程序输出:
新加入的元素为:a 新加入的元素为:b 新加入的元素为:c 新加入的元素为:d 新加入的元素为:e 当前容器的长度:5 移除的元素为:a 移除的元素为:b 新加入的元素为:f 新加入的元素为:g
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# Java多线程中线程间的通信
# java线程通信
# Java线程间的通信方式详解
# 深入理解JAVA多线程之线程间的通信方式
# java多线程实现服务器端与多客户端之间的通信
# 详谈java线程与线程、进程与进程间通信
# 浅析Java中如何实现线程之间通信
# 深入解析Java的线程同步以及线程间通信
# java线程间通信的通俗解释及代码示例
# java多线程编程学习(线程间通信)
# Java中实现线程间通信的实例教程
# 移除
# 多线程
# 另外一个
# 来实现
# 在这个
# 希望能
# 才可以
# 谢谢大家
# 排在
# 首位
# 需要注意
# 为空
# 取走
# 加锁
# 实现了
# 不停地
# RuntimeException
# start
# lt
# run
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何获取上海专业网站定制建站电话?
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
Android使用GridView实现日历的简单功能
如何快速生成橙子建站落地页链接?
黑客如何通过漏洞一步步攻陷网站服务器?
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
如何在万网ECS上快速搭建专属网站?
PHP正则匹配日期和时间(时间戳转换)的实例代码
微信小程序 配置文件详细介绍
如何快速搭建二级域名独立网站?
如何在阿里云服务器自主搭建网站?
Laravel如何自定义分页视图?(Pagination示例)
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
中国移动官方网站首页入口 中国移动官网网页登录
Laravel怎么使用Intervention Image库处理图片上传和缩放
Laravel如何使用Vite进行前端资源打包?(配置示例)
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
JS经典正则表达式笔试题汇总
创业网站制作流程,创业网站可靠吗?
网站制作免费,什么网站能看正片电影?
iOS UIView常见属性方法小结
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
如何制作一个表白网站视频,关于勇敢表白的小标题?
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
Laravel如何保护应用免受CSRF攻击?(原理和示例)
高防服务器租用如何选择配置与防御等级?
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
MySQL查询结果复制到新表的方法(更新、插入)
Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】
Linux系统命令中tree命令详解
高性能网站服务器配置指南:安全稳定与高效建站核心方案
如何快速搭建高效可靠的建站解决方案?
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】
打开php文件提示内存不足_怎么调整php内存限制【解决方案】
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
Swift中swift中的switch 语句
在线教育网站制作平台,山西立德教育官网?
如何快速搭建安全的FTP站点?
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
Laravel Admin后台管理框架推荐_Laravel快速开发后台工具
如何用低价快速搭建高质量网站?
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
如何快速重置建站主机并恢复默认配置?
LinuxCD持续部署教程_自动发布与回滚机制
详解vue.js组件化开发实践
简单实现jsp分页
如何在自有机房高效搭建专业网站?

