美文网首页
线程的 sleep() 方法与 wait() 方法的区别

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

作者: 分布式与微服务 | 来源:发表于2022-11-03 09:01 被阅读0次

总的来说,线程的 sleep() 方法和 wait() 方法有以下几点区别:

(1)sleep() 方法是 Thread 类中的方法,而 wait() 方法是 Object 类中的方法。

(2)sleep() 方法不会释放 lock,但是 wait() 方法会释放,而且会加入到等待队列中。

(3)sleep() 方法不依赖于同步器 synchronized(),但是 wait() 方法 需要依赖 synchronized 关键字。

(4)线程调用 sleep() 之后不需要被唤醒(休眠时开始阻塞,线程的监控状态依然保持着,当指定的休眠时间到了就会自动恢复运行状态),但是 wait() 方法需要被重新唤醒(不指定时间需要被别人中断)。

public class SleepDemo {
 
    public static final Object LOCK = new Object();
 
    public static void main(String[] args) {
        Stream.of("线程1", "线程2").forEach(a -> new Thread(a) {
            @Override
            public void run() {
                new SleepDemo().testSleep();
            }
        }.start());
    }
 
    private void testSleep() {
        synchronized (LOCK) {
            try {
                System.out.println(Thread.currentThread().getName() + "正在执行: " + System.currentTimeMillis() / 1000);
                // 休眠 2 s
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
            } catch (Exception e) {
 
            }
        }
    }
 
}

可以看到,线程 1 先抢到了资源,执行主体方法时要求睡眠 2 秒,那么在这两秒时间内,即使线程 1 没有任何动作,线程 2 也不能抢占资源。 需要注意的是,在调用 sleep() 方法时,如果有两个线程,那么要想实现线程睡眠的效果就需要使用 synchronized() 方法,否则达不到效果。

public class SleepDemo {
 
//    public static final Object LOCK = new Object();
 
    public static void main(String[] args) {
        Stream.of("线程1", "线程2").forEach(a -> new Thread(a) {
            @Override
            public void run() {
                new SleepDemo().testSleep();
            }
        }.start());
    }
 
    private void testSleep() {
//        synchronized (LOCK) {
            try {
                System.out.println(Thread.currentThread().getName() + "正在执行: " + System.currentTimeMillis() / 1000);
                // 休眠 2 s
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
            } catch (Exception e) {
                System.out.println(e);
            }
//        }
    }
 
}

如上所示,不使用 synchronized() 的话就会出现两个线程同时执行,同时睡眠,又同时恢复执行。

由此可知,调用 sleep() 方法时,并不是强依赖于 synchronized() 方法,如果我只有一个线程,那么使用 synchronized() 方法和不使用 synchronized() 方法的效果是一样的。如果有两个线程的话,也可以选择使用或者不使用 synchronized() 方法。但是 wait() 方法就不一样了,wait() 方法强依赖于 synchronized() 方法,如果不使用 synchronized() 方法的话,wait() 方法的程序就会报错。

public class WaitDemo {
 
    public static final Object LOCK = new Object();
 
    public static void main(String[] args) {
        Stream.of("线程1", "线程2").forEach(a -> new Thread(a) {
            @Override
            public void run() {
                WaitDemo.testWait();
            }
        }.start());
    }
 
    private static void testWait() {
//        synchronized (LOCK) {
            try {
                System.out.println(Thread.currentThread().getName() + "正在执行: " + System.currentTimeMillis() / 1000);
                // 等待 2 s
                LOCK.wait(2000);
                System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
//    }
 
}

使用 synchronized 关键字修饰后:

public class WaitDemo {
 
    public static final Object LOCK = new Object();
 
    public static void main(String[] args) {
        Stream.of("线程1", "线程2").forEach(a -> new Thread(a) {
            @Override
            public void run() {
                WaitDemo.testWait();
            }
        }.start());
    }
 
    private static void testWait() {
        synchronized (LOCK) {
            try {
                System.out.println(Thread.currentThread().getName() + "正在执行: " + System.currentTimeMillis() / 1000);
                // 等待 2 s
                LOCK.wait(2000);
                System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    }
 
}

因为在代码中有指定 wait(2000),所以当 2 秒之后该线程就会恢复执行的,而不用另外一个线程去唤醒,如果 wait() 方法没有指定时间的话,那么该线程就会一直等待~

除此之外,一个线程一旦被 wait 之后,就必须有另外一个线程去唤醒,否则一直处于等待状态。

public class WaitDemo {
 
    public static final Object LOCK = new Object();
 
    private void testWait1() {
        synchronized (LOCK) {
            try {
                System.out.println(Thread.currentThread().getName() + "开始执行: " + System.currentTimeMillis() / 1000);
                LOCK.wait();
                System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
 
    private void testNotify() {
        synchronized (LOCK) {
            try {
                Thread.sleep(2000);
                LOCK.notify();
                System.out.println(Thread.currentThread().getName() + "唤醒另一线程: " + System.currentTimeMillis() / 1000);
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
 
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                new WaitDemo().testWait1();
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                new WaitDemo().testNotify();
            }
        }.start();
    }
 
}

相关文章

  • sleep,wait,yield,join

    sleep和wait区别 sleep是线程Thread的方法,wait是Object的方法 都有使该线程暂时休眠的...

  • JAVA线程sleep和wait方法区别

    JAVA线程sleep和wait方法区别 一 sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时...

  • 线程的 sleep() 方法与 wait() 方法的区别

    总的来说,线程的 sleep() 方法和 wait() 方法有以下几点区别: (1)sleep() 方法是 Thr...

  • 线程

    线程与进程的区别: 理解线程的优先权 yield()方法 join()方法 线程的生命周期: sleep和wait...

  • Java基础之多线程

    1.Thread线程 线程中start和run方法有什么区别?wait和sleep方法的不同?sleep() 、j...

  • 线程各个方法区别

    sleep与wait 区别 对于sleep()方法,属于Thread类中的。而wait()方法,则是属于 Obje...

  • Java中线程生命周期

    Java中线程生命周期图如下线程生命周期 sleep() 和 wait() 方法的区别? 1 sleep方法是Th...

  • JAVA总结(三)

    Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? sleep()方...

  • 线程提问的点

    Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? sleep()方...

  • Java知识点总结基础篇51-53

    五十一、sleep()和wait()有什么区别 Sleep是线程类(Thread)的方法,导致此线程暂停执行指定时...

网友评论

      本文标题:线程的 sleep() 方法与 wait() 方法的区别

      本文链接:https://www.haomeiwen.com/subject/crwzwrtx.html