Java 中的 sleep、wait、join 怎么理解
在 Java 中,sleep()、wait() 和 join() 都是与线程同步和控制相关的常用方法,它们各自有不同的功能和使用场景。以下是它们的区别和联系的详细分析:
sleep()
sleep() 是 Thread 类中的静态方法,用于让当前线程暂停执行指定的时间,并进入 阻塞状态。暂停期间,线程仍然持有任何锁,也就是说,sleep() 不会释放对象锁。
使用场景:常用于让线程暂时休眠一段时间。
主要特点:
线程在指定的时间结束后会自动恢复运行。
sleep() 不释放线程已经持有的锁,只是会让出时间片,其他线程获取不到这个线程的资源 。
可以被 interrupt() 方法打断,从而抛出InterruptedException。
wait()
wait() 是 Object 类中的方法,用于让线程等待,直到其他线程调用同一对象的 notify() 或 notifyAll() 方法,才能继续执行。调用 wait() 时,线程会进入 等待状态,并且会释放它持有的 对象锁。
使用场景:通常用于线程间通信,允许一个线程等待另一个线程的执行结果或通知。
public final void wait() throws InterruptedException
public final void wait(long timeout) throws InterruptedException
主要特点:
线程必须在持有对象的锁(即在 synchronized 块内)时才能调用 wait()。
调用 wait() 后,线程会释放对象锁并进入等待状态,直到其他线程调用 notify() 或 notifyAll()。
wait() 必须和 notify() 或 notifyAll() 搭配使用。
可以设置超时时间来自动唤醒等待线程。
示例:
synchronized (lock) {lock.wait(); // 当前线程进入等待,并释放锁// 被唤醒后继续执行
}
join()
join() 是 Thread 类中的方法,用于让调用线程等待另一个线程完成执行。换句话说,调用某个线程的 join() 方法会让当前线程暂停,直到被调用的线程执行完毕。
使用场景:常用于确保一个线程的执行完毕之后,其他线程才能继续执行。
public final void join() throws InterruptedException
public final void join(long millis) throws InterruptedException
主要特点:
线程 A 调用线程 B 的 join() 方法时,线程 A 会进入阻塞状态,直到线程 B 执行完毕。
join() 可以设置超时时间,指定等待时间后,线程 A 可以继续执行,即使线程 B 未结束。
可以被 interrupt() 方法打断,抛出 InterruptedException。
示例:
Thread t = new Thread(() -> {// 线程执行逻辑
});
t.start();
t.join(); // 当前线程等待 t 线程执行完毕后再继续执行