前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >wait()和sleep()的区别

wait()和sleep()的区别

原创
作者头像
奇门水镜
发布2023-05-19 10:39:41
5550
发布2023-05-19 10:39:41
举报
文章被收录于专栏:政务云Openstack政务云Openstack
  • sleep()是Thread类的方法,用于让线程暂停一段时间,不释放对象锁。
  • wait()是Object类的方法,在同步代码块中使用,让线程等待并释放对象锁,直到被唤醒或超时。
  • sleep()是线程的静态方法,wait()是对象的方法。
  • sleep()通常用于控制执行时间间隔或模拟延迟,而wait()通常用于线程间的同步和协调。

需要注意的是,在使用wait()notify()时,必须在同步代码块或同步方法中调用,以确保正确的对象锁的释放和获取。

划重点:sleep()不会释放对象锁,而wait()会释放对象锁。

示例:

代码语言:javascript
复制
public class ObjectLockExample {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(new SleepThread());
        Thread thread2 = new Thread(new WaitThread());

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

    static class SleepThread implements Runnable {
        public void run() {
            synchronized (lock) {
                System.out.println("SleepThread acquired lock");

                try {
                    Thread.sleep(2000); // 线程暂停2秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("SleepThread released lock");
            }
        }
    }

    static class WaitThread implements Runnable {
        public void run() {
            synchronized (lock) {
                System.out.println("WaitThread acquired lock");

                try {
                    lock.wait(2000); // 线程等待2秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("WaitThread released lock");
            }
        }
    }
}

在上述代码中,我们创建了两个线程:SleepThreadWaitThread。它们都使用了同一个对象锁 lock

  • SleepThread在同步代码块中执行,并调用 Thread.sleep(2000) 来暂停执行2秒钟。在这个过程中,SleepThread保持了对 lock 对象锁的占有。
  • WaitThread在同步代码块中执行,并调用 lock.wait(2000) 来等待2秒钟。在等待期间,WaitThread会释放对 lock 对象锁的占有,并进入等待状态。
  • SleepThreadWaitThread 中的暂停或等待时间结束后,它们都会继续执行,并释放对 lock 对象锁的占有。

关于对象锁和 sleep()wait() 的操作,我们可以观察到以下情况:

  • sleep() 不释放对象锁,即使线程暂停执行,仍然持有对象锁,其他线程无法进入该同步代码块。
  • wait() 会释放对象锁,使得其他线程有机会获取该对象锁并执行相应的同步代码块。

这里调用的必须是lock对象的wait()方法。如果在等待期间,其他线程获得了相同对象锁并执行了关联的同步代码块,那么当notify()notifyAll()方法被调用唤醒等待的线程时,等待线程会继续执行,但是可能无法立即执行等待之后的代码。

当一个线程通过调用wait()方法释放对象锁后,它进入了等待状态,并等待其他线程调用相同对象上的notify()notifyAll()方法来唤醒它。在这段等待的时间内,其他线程有机会获取对象锁,并执行与之关联的同步代码块。

当调用notify()notifyAll()方法来唤醒等待的线程时,被唤醒的线程会重新竞争对象锁。然而,并不保证等待线程会立即获得对象锁。如果其他线程在等待线程之前抢占了对象锁,等待线程仍然需要等待其他线程释放对象锁后,才能再次获得对象锁并继续执行。

因此,在等待线程被唤醒后,它需要重新竞争对象锁,如果没有成功获得对象锁,它将继续等待,直到再次获得对象锁才能继续执行等待之后的代码。

需要注意的是,为了确保线程等待和唤醒的正确性,通常在使用wait()notify()notifyAll()时,需要遵循一定的编程规范,例如在同步代码块或同步方法中使用,避免竞争条件等。这样可以保证等待和唤醒的正确性,并避免可能的死锁或其他线程同步问题。

sleep()应用场景

  1. 定时任务sleep() 方法可以用于实现定时任务。通过在任务的执行过程中调用 sleep() 方法,可以使线程在指定的时间间隔内暂停执行。这对于需要按照一定时间间隔执行某个任务的场景非常有用。
  2. 模拟延迟sleep() 方法可以用于模拟程序执行中的延迟。在某些情况下,我们希望程序在执行过程中暂停一段时间,以模拟一些实际场景,比如网络请求的延迟、系统资源的加载等。
  3. 线程间的交互sleep() 方法可以用于线程间的交互和调度。通过控制不同线程的休眠时间,我们可以实现线程之间的交替执行或特定的执行顺序。
  4. 优化资源利用sleep() 方法可以用于优化资源的利用。当某个线程执行一些耗时操作,但在某些时候并不需要一直占用资源时,可以通过适当的休眠时间来减少 CPU 的占用,让其他线程有机会获得执行。

需要注意的是,sleep() 方法是一个简单的线程暂停方法,并不涉及线程的状态管理或线程间的通信。它只是让当前线程暂停执行,不会释放对象锁。因此,使用 sleep() 方法时需要注意与其他线程的协作和同步。

此外,还需要注意 sleep() 方法的精度和可靠性可能受到操作系统和系统负载等因素的影响。因此,在编写依赖于时间的逻辑时,应谨慎使用 sleep() 方法,并考虑使用更可靠的工具和机制来满足需求,例如 ScheduledExecutorServiceTimer 等。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档