当前位置: 首页 > news >正文

Java 中线程通信方式笔记

目录

  1. 线程通信的定义
  2. 使用 wait() / notify() 通信
  3. 使用 join() 实现线程串行
  4. 使用 volatile 实现可见性通信
  5. 使用 LockSupport
  6. 使用 Condition
  7. 使用 BlockingQueue
  8. 使用 CountDownLatchCyclicBarrierSemaphore
  9. 使用 Future / CompletableFuture
  10. 总结

1.线程通信的定义

线程通信是指多个线程在协同完成某个任务时,为了数据同步或协作调度而相互传递信息或等待状态变化的机制。

常见目的:

  • 数据共享同步(生产者-消费者)
  • 控制线程顺序(线程 A -> 线程 B)
  • 等待某一条件满足后继续执行

2.使用 wait() / notify() 通信

最基础的通信方式,依赖对象锁和监视器机制。

示例:

class Shared {private boolean ready = false;public synchronized void waitForSignal() throws InterruptedException {while (!ready) {wait(); // 释放锁 + 阻塞}System.out.println("Signal received!");}public synchronized void sendSignal() {ready = true;notify(); // 唤醒等待线程}
}

特点:

  • 必须配合 synchronized 使用
  • wait() 会释放锁,notify() 不会
  • 建议使用 while 判断条件防止虚假唤醒

3.使用 join() 实现线程串行

等待其他线程执行完成,适合线程之间有执行顺序依赖的场景。

示例:

Thread t1 = new Thread(() -> {System.out.println("T1 done");
});
Thread t2 = new Thread(() -> {try {t1.join();System.out.println("T2 done after T1");} catch (InterruptedException e) {}
});t1.start();
t2.start();

4.使用 volatile 实现可见性通信

适用于简单的标志状态共享,如线程停止。

示例:

class Flag {volatile boolean stop = false;
}Flag flag = new Flag();new Thread(() -> {while (!flag.stop) {// do work}
}).start();Thread.sleep(1000);
flag.stop = true;

特点:

  • 保证线程间变量的可见性
  • 不保证原子性
  • 适合轻量级信号传递

5.使用 LockSupport

线程阻塞和唤醒的底层工具,替代 wait/notify,无需加锁。

示例:

Thread t = new Thread(() -> {System.out.println("Thread park");LockSupport.park();System.out.println("Thread unparked");
});
t.start();Thread.sleep(1000);
LockSupport.unpark(t);

特点:

  • 每个线程有一个许可证(类似信号量)
  • 更灵活,不依赖同步锁
  • 常用于实现框架级线程调度

6.使用 Condition

Lock 的增强版 wait/notify,支持多个条件队列。

示例:

Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();Thread t1 = new Thread(() -> {lock.lock();try {condition.await(); // 类似 wait()System.out.println("Thread t1 resumed");} catch (InterruptedException e) {} finally {lock.unlock();}
});Thread t2 = new Thread(() -> {lock.lock();condition.signal(); // 类似 notify()lock.unlock();
});

特点:

  • 可精准唤醒特定条件队列中的线程
  • 支持多个等待队列

7.使用 BlockingQueue

适合生产者-消费者模式,线程安全队列内置通信机制。

示例:

BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);new Thread(() -> {try {queue.put(1); // 阻塞直到有空间} catch (InterruptedException e) {}
}).start();new Thread(() -> {try {Integer value = queue.take(); // 阻塞直到有元素System.out.println("Consumed: " + value);} catch (InterruptedException e) {}
}).start();

8.使用 CountDownLatch/CyclicBarrier/Semaphore

CountDownLatch

用于一个线程等待多个线程完成:

CountDownLatch latch = new CountDownLatch(2);new Thread(() -> {latch.countDown(); // 执行完毕
}).start();latch.await(); // 等待所有线程执行完

CyclicBarrier

适合多个线程在某个点同步:

CyclicBarrier barrier = new CyclicBarrier(3, () -> {System.out.println("All threads reached barrier");
});new Thread(() -> {barrier.await();
}).start();

Semaphore

用于控制线程数量(资源数):

Semaphore semaphore = new Semaphore(2); // 允许2个线程同时访问semaphore.acquire();
try {// 访问共享资源
} finally {semaphore.release();
}

9.使用 Future / CompletableFuture

线程间通过结果对象通信,适合异步执行与回调。

示例:

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {return "result";
});String result = future.get(); // 阻塞直到任务完成

CompletableFuture

CompletableFuture.supplyAsync(() -> "Hello").thenApply(str -> str + " World").thenAccept(System.out::println);

总结

方式适用场景是否阻塞特点
wait/notify精细通信必须配合锁
join等待线程完成简单串行依赖
volatile状态通知可见性但无原子性
LockSupport框架底层调度灵活、无锁
Condition多条件控制精细唤醒
BlockingQueue生产者消费者内置通信机制
CountDownLatch等待一组线程一次性门闩
CyclicBarrier多线程集结可重复使用
Semaphore控制访问数量控制并发度
Future/CompletableFuture异步编程支持回调返回值通信
http://www.dtcms.com/a/274075.html

相关文章:

  • tailwindCSS === 使用插件自动类名排序
  • ssm框架整合全攻略:从环境搭建到功能实现
  • 什么是Podman?能否替代Docker?Podman快速入门
  • dockerfile 笔记
  • STM32-DAC数模转换
  • 将英语转化为语音 英文转音频 英语转语音朗读
  • 嵌入式八股文之 GPIO
  • RISC-V:开源芯浪潮下的技术突围与职业新赛道 (三)RISC-V架构深度解剖(下)
  • FPGA实现SDI转LVDS视频发送,基于GTX+OSERDES2原语架构,提供2套工程源码和技术支持
  • Spring注解IoC与JUnit整合实战
  • MyBatis-Plus通用中等、大量数据分批查询和处理
  • 蔚来测开一面:HashMap从1.7开始到1.8的过程,既然都解决不了并发安全问题,为什么还要进一步解决环形链表的问题?
  • XPath 语法【Web 自动化-定位方法】
  • [java][springboot]@PostConstruct的介绍和用法
  • 机器学习基础知识【 激活函数、损失函数、优化器、 正则化、调度器、指标函数】
  • AI加持的开源知识库新秀:PandaWiki,如何用它打造智能化文档系统?
  • 「日拱一码」024 机器学习——防止过拟合
  • 【yolo】模型训练参数解读
  • 哪个ai写论文比较好?实测推荐这6大AI论文写作神器
  • CCF-GESP 等级考试 2025年6月认证C++五级真题解析
  • 2025年值得推荐的5款 AI赋能企业级项目管理软件工具大盘点!
  • Linux:多线程---同步生产者消费者模型
  • 【尝试】基于YoloV8做安全帽识别
  • 12. 说一下 https 的加密过程
  • 2025 年第十五届 APMCM 亚太地区大学生数学建模竞赛-B题 疾病的预测与大数据分析
  • CCN-508 规范
  • Web 网站性能优化之 Nginx 优化指南
  • 提示工程:突破Transformer极限的计算科学
  • S7-1200 系列 PLC 中 SCL 语言的 PEEK 和 POKE 指令使用详解
  • IDE 关联 Git 操作