Java 语言 条件变量如何精准唤醒线程

Java阿木 发布于 22 天前 2 次阅读


摘要:

在Java并发编程中,条件变量是用于线程间同步的一种机制。本文将深入探讨Java中条件变量的使用,特别是如何精准唤醒线程。我们将通过实例代码分析,展示如何使用`Object`类的`wait()`和`notify()`方法,以及`java.util.concurrent`包中的`ReentrantLock`和`Condition`接口来实现精准唤醒线程。

关键词:Java并发编程,条件变量,线程同步,wait/notify,ReentrantLock,Condition

一、

在多线程编程中,线程间的同步是确保数据一致性和程序正确性的关键。条件变量是Java中实现线程同步的一种重要机制。它允许一个或多个线程在某个条件不满足时等待,直到其他线程改变条件并通知它们。

二、条件变量的基本原理

在Java中,条件变量通常与`Object`类的`wait()`和`notify()`方法一起使用。当一个线程调用`wait()`方法时,它会释放当前持有的锁,并进入等待状态。当其他线程调用`notify()`或`notifyAll()`方法时,等待的线程可能会被唤醒。

三、使用wait/notify实现精准唤醒

以下是一个使用`wait()`和`notify()`方法实现精准唤醒线程的示例:

java

public class WaitNotifyExample {


private final Object lock = new Object();


private boolean ready = false;

public void condition() throws InterruptedException {


synchronized (lock) {


while (!ready) {


lock.wait();


}


// 条件满足,执行相关操作


System.out.println("Condition is true, executing task...");


}


}

public void signal() {


synchronized (lock) {


ready = true;


lock.notify();


}


}

public static void main(String[] args) throws InterruptedException {


WaitNotifyExample example = new WaitNotifyExample();


Thread t1 = new Thread(example::condition);


Thread t2 = new Thread(example::signal);

t1.start();


t2.start();

t1.join();


t2.join();


}


}


在这个例子中,`condition()`方法中的线程会一直等待`ready`变量变为`true`。一旦`signal()`方法被调用,`ready`变量被设置为`true`,并且调用`notify()`方法唤醒等待的线程。

四、使用ReentrantLock和Condition实现精准唤醒

Java 5引入了`java.util.concurrent.locks.ReentrantLock`和`java.util.concurrent.locks.Condition`,它们提供了更灵活的条件变量实现。

以下是一个使用`ReentrantLock`和`Condition`实现精准唤醒线程的示例:

java

import java.util.concurrent.locks.Condition;


import java.util.concurrent.locks.ReentrantLock;

public class LockConditionExample {


private final ReentrantLock lock = new ReentrantLock();


private final Condition condition = lock.newCondition();


private boolean ready = false;

public void condition() throws InterruptedException {


lock.lock();


try {


while (!ready) {


condition.await();


}


// 条件满足,执行相关操作


System.out.println("Condition is true, executing task...");


} finally {


lock.unlock();


}


}

public void signal() {


lock.lock();


try {


ready = true;


condition.signal();


} finally {


lock.unlock();


}


}

public static void main(String[] args) throws InterruptedException {


LockConditionExample example = new LockConditionExample();


Thread t1 = new Thread(example::condition);


Thread t2 = new Thread(example::signal);

t1.start();


t2.start();

t1.join();


t2.join();


}


}


在这个例子中,`condition()`方法使用`lock()`和`unlock()`来获取和释放锁,使用`await()`和`signal()`来等待和唤醒线程。

五、总结

本文通过实例代码展示了在Java中使用条件变量实现精准唤醒线程的方法。我们讨论了使用`wait()`/`notify()`和`ReentrantLock`/`Condition`两种方式,并分析了它们的优缺点。在实际应用中,应根据具体需求选择合适的方法来实现线程间的同步。