使用 Object 中的 wait()
方法让线程等待,使用 Object 中的 notify()
方法唤醒线程
<aside>
💡 wait()
和 notify()
方法必须在 synchronized
代码块中执行;将 notify 放在 wait 之前,程序无法执行
</aside>
使用 JUC 包中 Condition 的 await()
方法让线程等待,使用 signal()
方法唤醒线程
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadExample {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private boolean isConditionMet = false;
public void waitForCondition() throws InterruptedException {
lock.lock();
try {
while (!isConditionMet) {
System.out.println(Thread.currentThread().getName() + " 等待条件满足...");
condition.await(); // 等待条件满足
}
System.out.println(Thread.currentThread().getName() + " 条件已满足,继续执行!");
} finally {
lock.unlock();
}
}
public void signalCondition() {
lock.lock();
try {
System.out.println("条件已满足,唤醒等待的线程...");
isConditionMet = true;
condition.signal(); // 唤醒等待的线程
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ThreadExample example = new ThreadExample();
// 创建等待线程
Thread waitingThread = new Thread(() -> {
try {
example.waitForCondition();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "等待线程");
// 创建唤醒线程
Thread signalingThread = new Thread(() -> {
try {
// 假设需要一些时间来准备条件
Thread.sleep(2000);
example.signalCondition();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "唤醒线程");
// 启动线程
waitingThread.start();
signalingThread.start();
}
}
LockSupport 类可以阻塞当前线程以及唤醒指定被阻塞的线程
<aside> 💡 必须先等待后唤醒,如果顺序相反,等待会失去作用
</aside>
import java.util.concurrent.locks.LockSupport;
public class LockSupportExample {
static Thread t1, t2;
public static void main(String[] args) {
t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 - Iteration " + i);
if (i == 2) {
// 在第三次迭代时阻塞线程t1
LockSupport.park();
}
}
});
t2 = new Thread(() -> {
try {
// 让线程t2休眠一段时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 在t2执行后,解除t1的阻塞
System.out.println("Thread 2 - Unparking Thread 1");
LockSupport.unpark(t1);
});
t1.start();
t2.start();
}
}
import java.util.concurrent.locks.LockSupport;
public class UnparkBeforeParkExample {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("Thread 1 - Trying to park");
LockSupport.park(); // 尝试阻塞,但由于先调用了unpark,因此不会阻塞
System.out.println("Thread 1 - Resumed after park");
});
// 先调用unpark
System.out.println("Main - Unparking Thread 1");
LockSupport.unpark(t1);
// 稍微等待一下,确保unpark先执行
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 再启动线程
t1.start();
}
}
由以上两个例子,可以看出:
LockSupport
可以直接使用unpark()
可以在 park()
之前调用与 Object 的 wait & notify 相比