学静思语
Published on 2025-03-21 / 14 Visits
0
0

Java多线程中wait()与sleep()方法的区别

Java多线程中wait()与sleep()方法的区别

wait()和sleep()在Java多线程编程中都能使线程暂停执行,但它们有本质区别:

1. 所属类不同

  • wait(): 属于Object类的方法,所有Java对象都可调用
  • sleep(): 属于Thread类的静态方法,只能通过Thread类或线程对象调用

2. 锁资源处理不同

  • wait(): 释放当前持有的对象锁,允许其他线程获取该锁
  • sleep(): 不释放锁资源,即使线程休眠,仍然保持对锁的占用

3. 调用位置要求

  • wait(): 必须在synchronized同步块或同步方法中调用,否则会抛出IllegalMonitorStateException
  • sleep(): 可以在任何地方调用,无需在同步上下文中

4. 唤醒机制不同

  • wait(): 需要通过notify()/notifyAll()方法或中断来唤醒
  • sleep(): 时间到后自动唤醒,或者可以通过interrupt()方法提前唤醒

5. 使用场景不同

  • wait(): 用于线程间协作与通信,实现线程间的等待/通知机制
  • sleep(): 主要用于使当前线程暂停执行指定的时间,不涉及线程间通信

6. 异常处理不同

  • wait(): 抛出InterruptedException和IllegalMonitorStateException
  • sleep(): 只抛出InterruptedException

代码示例

wait()方法示例:

public class WaitExample {
    public static void main(String[] args) {
        final Object lock = new Object();

        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程1获取到锁");
                try {
                    System.out.println("线程1调用wait()方法");
                    lock.wait(); // 释放锁,等待被唤醒
                    System.out.println("线程1被唤醒");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(1000); // 确保线程1先执行
                synchronized (lock) {
                    System.out.println("线程2获取到锁");
                    lock.notify(); // 唤醒等待的线程
                    System.out.println("线程2通知完成");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
    }
}

sleep()方法示例:

public class SleepExample {
    public static void main(String[] args) {
        final Object lock = new Object();

        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程1获取到锁");
                try {
                    System.out.println("线程1调用sleep()方法");
                    Thread.sleep(3000); // 不释放锁,只是让线程休眠
                    System.out.println("线程1休眠结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(1000); // 确保线程1先执行
                System.out.println("线程2尝试获取锁");
                synchronized (lock) {
                    System.out.println("线程2获取到锁"); // 只有在线程1释放锁后才能执行到这里
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
    }
}

总结来说,wait()主要用于线程间协作,会释放锁并等待通知;而sleep()主要用于控制线程执行节奏,不释放锁资源。在实际多线程编程中,理解并正确使用这两个方法对于实现高效的线程同步至关重要


Comment