Java线程进入等待

在Java中,线程是程序的执行单元。在多线程的环境中,有时候我们希望某个线程等待一段时间后再继续执行,或者等待某个条件满足后再继续执行。这时候,我们可以让线程进入等待状态。

线程等待的方法

Java提供了几种方法来使线程进入等待状态:

  • Thread.sleep(long millis):让当前线程休眠指定的毫秒数。
  • Object.wait():让当前线程进入等待状态,并释放对象的锁。
  • Object.wait(long timeout):让当前线程进入等待状态,并在指定的时间内等待,超过时间后自动唤醒。
  • Object.wait(long timeout, int nanos):让当前线程进入等待状态,并在指定的时间内等待,超过时间后自动唤醒,可以精确到纳秒级别。

Thread.sleep()方法的使用

Thread.sleep()方法是最简单的一种让线程进入等待状态的方法。它可以让线程休眠指定的毫秒数,然后自动唤醒。

下面是一个示例代码:

public class SleepExample {
    public static void main(String[] args) {
        System.out.println("线程开始执行");
        try {
            Thread.sleep(2000); // 线程休眠2秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程继续执行");
    }
}

在上面的代码中,主线程执行到Thread.sleep(2000)时,会让当前线程休眠2秒。然后在2秒后,主线程继续执行,并输出"线程继续执行"。

Object.wait()方法的使用

Object.wait()方法可以让当前线程进入等待状态,并释放对象的锁。当其他线程调用相同对象的notify()notifyAll()方法时,被等待的线程会被唤醒,并重新竞争对象的锁。

下面是一个示例代码:

public class WaitExample {
    public static void main(String[] args) {
        final Object lock = new Object();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println("线程A开始执行");
                    try {
                        lock.wait(); // 线程A进入等待状态
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程A继续执行");
                }
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println("线程B开始执行");
                    lock.notify(); // 唤醒等待的线程A
                    System.out.println("线程B继续执行");
                }
            }
        });

        threadA.start();
        try {
            Thread.sleep(1000); // 确保线程A先执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadB.start();
    }
}

在上面的代码中,线程A在执行到lock.wait()时,它会释放对象lock的锁,并进入等待状态。然后线程B执行lock.notify()方法,唤醒线程A,并继续执行。

序列图

下面是上述示例代码的序列图:

sequenceDiagram
    participant ThreadA as 线程A
    participant ThreadB as 线程B
    participant Lock as 对象lock

    activate ThreadA
    ThreadA->>Lock: synchronized
    Note over ThreadA,Lock: 线程A开始执行
    ThreadA->>Lock: wait()
    deactivate ThreadA

    activate ThreadB
    ThreadB->>Lock: synchronized
    Note over ThreadB,Lock: 线程B开始执行
    ThreadB->>Lock: notify()
    Note over ThreadB,Lock: 唤醒线程A
    deactivate ThreadB

    activate ThreadA
    Note over ThreadA,Lock: 线程A继续执行
    deactivate ThreadA

总结

通过使用Thread.sleep()方法和Object.wait()方法,我们可以让线程进入等待状态