Java 中线程之间如何进行通信?
Java 中线程之间如何进行通信?
回答重点
在 Java 中,线程之间的通信是指多个线程协同工作,主要实现方式包括:
1)共享变量:
- 线程可以通过访问共享内存变量来交换信息(需要注意同步问题,防止数据竞争和不一致)。
- 共享的也可以是文件,例如写入同一个文件来进行通信。
2)同步机制:
- synchronized:Java 中的同步关键字,用于确保同一时刻只有一个线程可以访问共享资源,利用 Object 类提供的
wait()、notify()、notifyAll()实现线程之间的等待/通知机制 - ReentrantLock:配合 Condition 提供了类似于 wait()、notify() 的等待/通知机制
- BlockingQueue:通过阻塞队列实现生产者-消费者模式
- CountDownLatch:可以允许一个或多个线程等待,直到在其他线程中执行的一组操作完成
- CyclicBarrier:可以让一组线程互相等待,直到到达某个公共屏障点
- Volatile:Java 中的关键字,确保变量的可见性,防止指令重排
- Semaphore:信号量,可以控制对特定资源的访问线程数
补充 Object 中的方法说明:
- wait():使线程进入等待状态,释放锁。
- notify():唤醒单个等待线程。
- notifyAll():唤醒所有等待线程。
扩展知识
wait/notify 机制的详细解读
wait() 会让线程进入阻塞状态,直到调用 notify() 或 notifyAll() 方法,通常结合 synchronized 使用,确保线程获取对象锁后再调用。
例如在经典的生产者-消费者模式中,生产者线程生产数据,如果缓冲区满了,则调用 wait(),等待消费者消费数据后再继续;消费者线程则通过 notify() 唤醒生产者。
示例代码:
1 | synchronized (lock) { |
Lock 和 Condition
ReentrantLock 提供了更灵活的锁机制,可以中断等待锁的线程,或进行尝试获取锁的操作。
Condition 对象类似于 wait()、notify() 的功能,但一个 Lock 可以创建多个 Condition,从而支持多个条件队列。
示例代码:
1 | Lock lock = new ReentrantLock(); |
BlockingQueue
BlockingQueue 是线程安全的阻塞队列,广泛应用于生产者-消费者模型。生产者通过 put() 方法将元素放入队列,如果队列满了,生产者线程会被阻塞;消费者通过 take() 方法从队列中取元素,如果队列为空,消费者线程会被阻塞。
示例代码:
1 | BlockingQueue<String> queue = new LinkedBlockingQueue<>(10); |
Comments