java多线程-sleep()方法和wait()方法

一、wait()方法

  • wait方法是Object的方法,是每一个类都拥有的一个方法
  • wait()方法一般和notify()/notifyAll()、synchronized(Object){..}一起用.同时Object.wait()必须在synchronized(Object object){}代码块中使用
  • 当调用wait方法的时候会释放对象锁,
  • 当调用notify()方法时只是会唤醒一个线程从等待队列转换到lock blocked pool中,等一个线程执行完毕以后,JVM会让线程获得对象锁

二、sleep()方法

  • sleep()是Thread类的静态方法,当调用此方法时,拥有的是一个Thread类锁,那么为什么在一个线程中调用此方法会阻止其他线程的运行??
  • 网上说sleep()不会释放对象锁,这个对象指的是谁??其实这个对象指的就是synchronized关键字锁住的那个对象
  • 下面的例子中说在主线程中调用sleep()方法以后,其他线程就都会休眠,而在自己的线程中调用sleep()方法说不会释放对象锁,在Thread2获得的是SleepAndWait的对象锁,调用sleep()并不会释放synchronized锁住的那个锁就是SleepAndWait对象锁。
  • 但是在主线程中调用sleep方法的时候,那么主线程获得是哪个对象的锁,sleep()方法是一个静态方法,获得的肯定是一个类锁,而不是一个对象锁???
package java_lang_Object;

/**
 * Created by luckyboy on 2018/7/4.
 */
public class SleepAndWait {
    public static void main(String[] args){

        new Thread(new Thread1()).start();


        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(new Thread2()).start();
    }

}
class Thread1 implements Runnable{

    @Override
    public void run() {
       synchronized (SleepAndWait.class){
            System.out.println("thread1 has entered..."+System.currentTimeMillis());
            System.out.println("thread1 is waiting..."+System.currentTimeMillis());
            try{
                SleepAndWait.class.wait();              
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thread1 is going on....."+System.currentTimeMillis());
            System.out.println("thread1 is over....."+System.currentTimeMillis());
        }

    }
}
class Thread2 implements Runnable{

    @Override
    public void run() {
        synchronized (SleepAndWait.class){
            System.out.println("thread2 has entered..."+System.currentTimeMillis());
            System.out.println("thread2 is sleeping..."+System.currentTimeMillis());

            SleepAndWait.class.notify();

            try{
                Thread.sleep(5000);

            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println("thread2 is going on....."+System.currentTimeMillis());
            System.out.println("thread2 is over....."+System.currentTimeMillis());
        }
    }
}

输出结果

thread1 has entered...1532700544787
thread1 is waiting...1532700544787
thread2 has entered...1532700549788
thread2 is sleeping...1532700549788
thread2 is going on.....1532700554789
thread2 is over.....1532700554789
thread1 is going on.....1532700554789
thread1 is over.....1532700554790

结果分析:

我们可以看到,当线程Thread1开始执行以后,进入到同步代码块中,然后调用了从Object中继承的方法wait(),这个时候,Thread1就进入了等待队列中,如果锁住的这个对象没有在别处调用notify()方法,那么Thread1就会无线等待下去。

一旦Thread1调用wait(),此时主线程就开始执行Thread.sleep()方法将会睡眠5s钟。一旦睡眠结束,Thread2被创建,同时获得SleepAndWait对象锁。并使用SleepAndWait.class.notify()方法唤醒在等待状态的Thread1。此时我们需要注意的是,我们的Thread2并没有马上放弃SleepAndWait对象锁。而是睡眠了5s钟以后执行完程序以后退出run()方法,释放synchronized对象锁。这个时候Thread1重新获得对象锁执行结束。

参考文章

https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值