线程间常见的通信方式主要有6种,核心是实现线程间的状态感知或数据传递。

    1.    volatile 与 synchronized 关键字:volatile 保证变量修改的可见性,让所有线程看到最新值;synchronized 保证同一时刻只有一个线程执行代码,兼具可见性与排他性。

简单来说,volatile 像“广播通知”,确保变量更新后所有线程都能看到;而 synchronized 像“单门独卫”,只允许一个线程进入操作,同时保证操作结果对后续线程可见。

    2.    等待/通知机制:通过 Object 类的 wait()、notify() 方法实现,一个线程修改数据后通知其他线程,实现状态联动(如生产消费模型)。

需要注意的是,它必须在 synchronized 同步块/方法 中使用,因为 wait() 调用时会释放对象锁,而获取锁是调用这两个方法的前提,否则会抛出 IllegalMonitorStateException 异常。

    3.    管道输入/输出流:基于内存传输数据,分为字节流(PipedOutputStream/InputStream)和字符流(PipedWriter/Reader),适用于线程间直接传递数据。

需要注意的是,使用时必须将输入流和输出流手动连接(如调用 connect() 方法),否则会抛出 IOException;且若一方未读取/写入数据,另一方会阻塞,避免数据丢失。

    4.    Thread.join() 方法:让当前线程等待目标线程执行完毕后再继续,常用于线程执行顺序控制,支持超时设置(join(long millis))。

需要注意的是,若目标线程被中断(interrupt),当前线程会抛出InterruptedException;而带超时的join(long millis),即使目标线程未完成,超时后当前线程也会自动恢复执行。

    5.    ThreadLocal:为每个线程创建独立的变量副本,实现线程数据隔离,避免共享变量竞争(如存储线程上下文信息)。

需要注意的是,ThreadLocal 存在内存泄漏风险:若线程长期存活(如线程池),且未手动调用 remove() 清除副本,副本对象会一直被线程引用无法回收,因此使用后建议主动清理。

    6.    并发工具类:如 CountDownLatch(倒计时等待)、CyclicBarrier(线程同步屏障)、Semaphore(信号量控制并发数),用于复杂场景下的线程协同。

简单区分三者核心差异:

    •    CountDownLatch:“一次性倒计时”,主线程等N个线程完成后再执行,计数到0就失效。

    •    CyclicBarrier:“可循环屏障”,让N个线程互相等待,全部到达屏障后再一起继续,可重复使用。

    •    Semaphore:“并发数控制器”,像停车场闸机,只允许指定数量的线程同时进入临界区。

 

 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐