java sleep和wait区别

本文详细对比了Java中sleep和wait方法的区别,解释了两者在资源锁释放上的不同行为,通过实例展示了线程间的交互过程,包括资源锁的获取、释放及等待线程的唤醒机制。

关于sleep和wait区别解析:

sleep只是释放CPU资源,并不释放资源锁对象,wait是会释放掉资源锁对象。

比如,有个锁对象object,线程1和线程2都会锁住object对象。运行线程1,线程1中使用wait方法,这个时候,线程1就处于卡死状态了,这时候我们运行线程2,线程2中使用sleep。这时候,如果资源锁没有释放,线程2是不会被执行的,因为资源锁被线程1占用,但是wait会释放资源锁,所以现象就是,线程1会执行,并且拿到资源锁。

搞个例子来看下:

public static Object lock = new Object();
//开启一个线程1
new Thread(() ->
{
    //首先搞个锁对象
    synchronized (lock) {
        System.out.println("线程1已拿到资源锁对象");
        try {
            //注意此处的区别
            //lock.wait(5000);
            Thread.sleep(5000);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("线程1资源锁准备释放");
    }

}).start();

Thread.sleep(10);

//开启一个线程2
new Thread(() ->
{
    //首先搞个锁对象
    synchronized (lock) {
        System.out.println("线程2已拿到资源锁对象");
        try {
            Thread.sleep(1000);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("线程2资源锁准备释放");
    }
}).start();

注意线程1中注释的代码,我们先来看下都是sleep情况下的结果,如下图,线程1资源释放后,线程2才能拿到锁继续执行。

3ddfad9ce09b0efa4f22850b0234cb9aca7.jpg

接下来我们把线程1中的sleep换成wati方法来看下结果,线程1拿到资源锁后,调用wait会释放资源锁,这时线程2就可以拿到锁的。如果线程1wait到时间后会继续执行。

466149f1d6be24110a6fc4146147886cb83.jpg

接下来测试下,wait唤醒后是否会拿到锁后执行,还是不用拿锁执行。调整下代码,线程1中的wait去掉时间设定,改为手工唤醒。线程2中添加唤醒线程1的方法,然后运行程序看下结果。

//开启一个线程1
new Thread(() ->
{
    //首先搞个锁对象
    synchronized (lock) {
        System.out.println("线程1已拿到资源锁对象");
        try {
            //注意此处的区别
            lock.wait();
            //Thread.sleep(5000);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("线程1资源锁准备释放");
    }

}).start();

Thread.sleep(10);

//开启一个线程2
new Thread(() ->
{
    //首先搞个锁对象
    synchronized (lock) {
        System.out.println("线程2已拿到资源锁对象");
        try {
            Thread.sleep(1000);
            //测试线程1是否会再次拿到锁对象
            lock.notify();
            System.out.println("已唤醒线程1");
            Thread.sleep(3000);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("线程2资源锁准备释放");
    }
}).start();

线程2唤醒线程1后,线程1并没有马上执行,而是等到线程2将资源锁释放后,线程1才开始执行。

722859a9f1ca2c33641b912ad01b4d11d93.jpg

 

让线程睡眠今天发现还有另外一种方式,本质上其实还是Thread.sleep()

TimeUnit.SECONDS.sleep(4);

 

 

转载于:https://my.oschina.net/uwith/blog/3002557

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值