多角度理解 Java 中线程休眠的四种方法
2024-01-13 14:01:12
如何在 Java 中让线程休眠?
当你在编写 Java 多线程程序时,有时需要让线程休眠一段时间,以便等待某个条件满足或资源可用。在 Java 中,有多种方法可以实现线程休眠,每种方法都有其独特的特点和应用场景。本文将详细介绍 Java 中四种常见的线程休眠方法:wait()
, sleep()
, join()
和 yield()
,帮助你深入理解线程休眠的原理和应用场景,从而在实际项目中更好地控制和管理多线程任务。
1. wait() 方法
wait()
方法是 Java 中最常用的线程休眠方法之一。它属于 Object
类,因此可以被任何 Java 对象调用。当调用 wait()
方法时,当前线程会释放对象的锁,并进入休眠状态。当另一个线程调用同一个对象的 notify()
或 notifyAll()
方法时,当前线程会被唤醒并继续执行。
public class WaitExample {
private final Object lock = new Object();
public void doSomething() {
synchronized (lock) {
while (conditionNotMet) {
try {
lock.wait();
} catch (InterruptedException e) {
// 处理中断异常
}
}
// 条件满足,继续执行
}
}
public void notifyOtherThreads() {
synchronized (lock) {
lock.notifyAll();
}
}
}
在上面的示例中,doSomething()
方法使用 wait()
方法让当前线程休眠,直到 conditionNotMet
为 false
。当另一个线程调用 notifyOtherThreads()
方法时,doSomething()
方法中的线程会被唤醒并继续执行。
2. sleep() 方法
sleep()
方法是另一个常用的线程休眠方法。它属于 Thread
类,因此只能被线程调用。当调用 sleep()
方法时,当前线程会休眠指定的时间,然后自动唤醒并继续执行。
public class SleepExample extends Thread {
@Override
public void run() {
try {
Thread.sleep(5000); // 休眠 5 秒
} catch (InterruptedException e) {
// 处理中断异常
}
// 休眠结束后继续执行
}
}
在上面的示例中,SleepExample
类继承了 Thread
类,并重写了 run()
方法。在 run()
方法中,线程调用 sleep()
方法休眠 5 秒,然后继续执行。
3. join() 方法
join()
方法允许一个线程等待另一个线程完成执行。当调用 join()
方法时,当前线程会等待指定线程执行完成,然后再继续执行。
public class JoinExample extends Thread {
@Override
public void run() {
// 执行一些任务
try {
Thread.sleep(5000); // 休眠 5 秒
} catch (InterruptedException e) {
// 处理中断异常
}
}
public static void main(String[] args) {
JoinExample thread = new JoinExample();
thread.start();
try {
thread.join(); // 等待 thread 线程执行完成
} catch (InterruptedException e) {
// 处理中断异常
}
// thread 线程执行完成,继续执行主线程
}
}
在上面的示例中,JoinExample
类继承了 Thread
类,并重写了 run()
方法。在 run()
方法中,线程执行一些任务,然后休眠 5 秒。在主线程中,调用 join()
方法等待 thread
线程执行完成,然后继续执行主线程。
4. yield() 方法
yield()
方法允许当前线程让出处理器的时间片,以便其他线程有机会执行。当调用 yield()
方法时,当前线程会将处理器的控制权让给其他就绪线程,然后自己进入就绪状态。如果当前线程是唯一一个就绪线程,那么 yield()
方法不会有任何效果。
public class YieldExample extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread " + Thread.currentThread().getName() + ": " + i);
if (i % 2 == 0) {
Thread.yield(); // 让出处理器的时间片
}
}
}
public static void main(String[] args) {
YieldExample thread1 = new YieldExample();
YieldExample thread2 = new YieldExample();
thread1.start();
thread2.start();
}
}
在上面的示例中,YieldExample
类继承了 Thread
类,并重写了 run()
方法。在 run()
方法中,线程循环输出数字,并每隔两个数字就调用 yield()
方法让出处理器的时间片。在主线程中,启动两个 YieldExample
线程,这两个线程会交替执行,输出数字。