在Java多线程编程中,线程间通信主要通过以下几种方式实现:
wait() 和 notify() / notifyAll() 方法: 这些方法是Object类的成员方法,因此所有对象都可以使用它们来进行线程间的协作。当一个线程调用某个对象的wait()方法时,它会释放该对象的锁并进入等待状态,直到另一个线程调用同一个对象的notify()或notifyAll()方法来唤醒它。notify()只会随机唤醒一个等待线程,而notifyAll()会唤醒所有等待线程。
synchronized (lock) {
try {
lock.wait(); // 线程进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
// 等待被唤醒后的操作
}
synchronized (lock) {
lock.notify(); // 唤醒一个等待线程
// 或者使用 lock.notifyAll(); 唤醒所有等待线程
}
Condition接口: Condition接口提供了比wait()和notify()更灵活的线程协作机制。它通常与ReentrantLock一起使用,可以通过lock.newCondition()创建一个Condition对象。Condition对象提供了await()、signal()和signalAll()方法,分别对应于Object的wait()、notify()和notifyAll()。
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
condition.await(); // 线程进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
// 等待被唤醒后的操作
lock.lock();
try {
condition.signal(); // 唤醒一个等待线程
// 或者使用 condition.signalAll(); 唤醒所有等待线程
} finally {
lock.unlock();
}
BlockingQueue接口: BlockingQueue是一个线程安全的队列,它提供了阻塞的put()和take()方法。当队列满时,put()方法会阻塞直到有空间可用;当队列为空时,take()方法会阻塞直到有元素可取。这种方式常用于生产者-消费者模式。
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
// 生产者线程
queue.put(1); // 如果队列满,则阻塞
// 消费者线程
int item = queue.take(); // 如果队列为空,则阻塞
CountDownLatch类: CountDownLatch允许一个或多个线程等待其他线程完成操作。它通过一个计数器来实现,该计数器的初始值为线程的数量。每当一个线程完成了任务,计数器的值就会减一。当计数器的值变为0时,表示所有线程都已完成任务,然后在等待的线程就可以继续执行了。
CountDownLatch latch = new CountDownLatch(2);
new Thread(() -> {
// 执行任务
latch.countDown(); // 计数器减一
}).start();
new Thread(() -> {
// 执行任务
latch.countDown(); // 计数器减一
}).start();
try {
latch.await(); // 等待计数器变为0
} catch (InterruptedException e) {
e.printStackTrace();
}
CyclicBarrier类: CyclicBarrier允许一组线程互相等待,直到所有线程都到达一个屏障点。与CountDownLatch不同的是,CyclicBarrier可以重复使用。当所有线程都到达屏障点时,屏障会自动重置,允许下一轮的线程协作。
CyclicBarrier barrier = new CyclicBarrier(2, () -> {
// 所有线程到达屏障点后执行的操作
});
new Thread(() -> {
// 执行任务
try {
barrier.await(); // 等待其他线程
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
// 执行任务
try {
barrier.await(); // 等待其他线程
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
Semaphore类: Semaphore是一个计数信号量,用于控制同时访问某一资源的线程数量。它维护了一组许可证,线程在访问资源前需要获取许可证,访问结束后释放许可证。如果许可证已全部被占用,那么请求的线程将被阻塞,直到有许可证可用。
Semaphore semaphore = new Semaphore(2); // 允许最多两个线程同时访问
new Thread(() -> {
try {
semaphore.acquire(); // 获取许可证
// 访问资源
semaphore.release(); // 释放许可证
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
这些是Java多线程中常用的线程间通信机制。在实际应用中,可以根据具体需求选择合适的机制来实现线程间的协作。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。