返回

多角度理解 Java 中线程休眠的四种方法

后端

如何在 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() 方法让当前线程休眠,直到 conditionNotMetfalse。当另一个线程调用 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 线程,这两个线程会交替执行,输出数字。