juc线程通信

├── 五、线程通信

│ ├── wait / notify
│ ├── Condition

│ ├── CountDownLatch

Object Condition
wait() await()
notify() signal()
notifyAll() signalAll()
复制代码
复制代码
ReentrantLock

synchronized + wait/notify

只能有一个等待队列:

复制代码
锁对象
 |
 |-- wait线程1
 |-- wait线程2
 |-- wait线程3

Condition 可以创建多个等待队列:

复制代码
ReentrantLock

    |
    +-- Condition A
    |       |
    |       +-- 等待线程
    |
    +-- Condition B
            |
            +-- 等待线程

可以精确唤醒不同类型线程。

│ ├──Semaphore

Semaphore 是 Java JUC(java.util.concurrent)提供的信号量工具,用于:

控制同时访问某个资源的线程数量。

Semaphore 内部维护一个许可证(permit)数量:

例如:

复制代码
Semaphore semaphore =
        new Semaphore(3);

表示:

复制代码
许可证数量 = 3

线程进入:

复制代码
acquire()

获取许可证:

复制代码
3

线程A获取

2

线程B获取

1

线程C获取

0

线程D等待

释放:

复制代码
release()

归还许可证:

复制代码
0

release()

1

线程D可以进入

acquire() 获取许可证:

release() 释放许可证:

tryAcquire() 尝试获取:

│ ├──CyclicBarrier

CountDownLatch 是 Java JUC(java.util.concurrent)提供的线程同步工具

让一个或多个线程等待其他线程完成后再继续执行。

CountDownLatch 内部维护一个计数器:

复制代码
CountDownLatch(3)

表示:

复制代码
count = 3

有 3 个任务需要完成。

每完成一个:

复制代码
countDown()

计数减一:

复制代码
3
 |
任务1完成
 |
2
 |
任务2完成
 |
1
 |
任务3完成
 |
0

当:

复制代码
count == 0

等待的线程继续执行。
CountDownLatch(3)

|


| | |

配置加载 缓存加载 数据库加载

↓ ↓ ↓

countDown() countDown() countDown()

count = 0

主线程继续启动

import java.util.concurrent.CountDownLatch;

public class Test {

public static void main(String\[\] args)

throws InterruptedException {

CountDownLatch latch =

new CountDownLatch(3);

for(int i=1;i<=3;i++){

new Thread(() -> {

System.out.println(

Thread.currentThread().getName()

+" 执行任务"

);

try {

Thread.sleep(1000);

} catch(Exception e){

}

//任务完成

latch.countDown();

}).start();

}

//等待所有任务完成

latch.await();

System.out.println(

"所有任务完成,主线程继续"

);

}

}

│ ├── Phaser

Phaser 是 Java JUC(java.util.concurrent)提供的多阶段线程同步工具

复制代码
java.util.concurrent.Phaser

JDK 7 引入。

让多个线程分阶段执行任务,每个阶段完成后等待其他线程,然后进入下一阶段。

CyclicBarrier + CountDownLatch 的增强版。

CountDownLatch

  • 只能等待一次
  • 数量固定

例如:

复制代码
任务1完成
任务2完成
任务3完成

count = 0

结束

不能重新开始。

CyclicBarrier

  • 可以循环
  • 但是参与线程数量固定

Phaser

  • 支持多个阶段
  • 支持动态增加/减少线程
  • 每个阶段可以执行不同逻辑
│ └── Exchanger

Exchanger 是 Java JUC(java.util.concurrent)提供的线程间数据交换工具

让两个线程在某个同步点交换数据。

线程A 手里有数据A

线程B 手里有数据B

Exchanger

线程A 得到数据B

线程B 得到数据A

exchange() exchange(timeout)

交换数据:

String result =

exchanger.exchange("hello");

java 复制代码
import java.util.concurrent.Exchanger;


public class Test {


    public static void main(String[] args) {


        Exchanger<String> exchanger =
                new Exchanger<>();


        new Thread(() -> {

            try {

                String data =
                    "生产的数据";


                System.out.println(
                    "线程A发送:"
                    + data
                );


                String result =
                    exchanger.exchange(data);


                System.out.println(
                    "线程A收到:"
                    + result
                );


            } catch(Exception e){

            }


        }).start();



        new Thread(() -> {

            try {

                String data =
                    "消费的数据";


                System.out.println(
                    "线程B发送:"
                    + data
                );


                String result =
                    exchanger.exchange(data);


                System.out.println(
                    "线程B收到:"
                    + result
                );


            } catch(Exception e){

            }


        }).start();

    }

}
特点 说明
核心作用 两个线程在同步点交换数据
参与线程数量 固定两个线程进行交换
交换方式 一方提交数据,等待另一方提交数据,然后互换
是否阻塞 是,没有另一方到达时会阻塞等待
是否可重复使用 ✅ 可以,多次调用 exchange()
是否支持超时 ✅ 支持
是否支持中断 ✅ 支持线程中断
数据类型 泛型,可以交换任意对象
是否基于 AQS ❌ 不是
底层实现 CAS + 等待槽(Slot)机制
典型场景 双缓冲、生产消费交换、数据校验

如果 ExchangerA 线程发了数据,但是 B 线程没有调用 exchange()

A 会一直阻塞等待 B 到达交换点。

Java 并发同步体系

复制代码
java.util.concurrent

├── CountDownLatch
│      等待一次性任务完成
│
├── CyclicBarrier
│      多线程循环集合
│
├── Phaser
│      多阶段动态同步
│
├── Semaphore
│      控制并发数量
│
└── Exchanger
       两线程交换数据
复制代码
相关推荐
benbenAItalk5 小时前
数字人口播视频的批量生产实践:素材规范、任务编排与质量验收
java·前端·音视频
sunshine22 girl5 小时前
Java学习二 基本语法2, 算术运算符
java·学习
2601_966949655 小时前
为什么量化策略需要大量历史股票数据?从回测可信度理解数据规模
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
niucloud-admin5 小时前
JAVA V6 多商户商城 开发文档——插件目录结构
java·开发语言
2601_962885725 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
滕州市燕猫虎计算机科技工作室个体工商户5 小时前
Java锁
java·开发语言
多加点辣也没关系6 小时前
JavaScript|第31章:表单与控件
开发语言·javascript·ecmascript
菜鸟~noob2336 小时前
【电子战】 第09篇:阵列信号处理——波束形成、MVDR、MUSIC【含matlab代码】
开发语言·matlab·信号处理
ocean21036 小时前
2025-2026年Python面试高频知识点洞察
开发语言·python·面试·python八股文
零依赖极客6 小时前
Day 6·1 ARMv8.2 dotprod——vdotq_s32 一条指令做 4 个点积
c语言·开发语言·人工智能·矩阵·arm·vllm