sleep与wait区别

简介: 第一个区别是在对系统资源的占用上。wait是Object类的一个函数(也就意味着所有对象都有这个函数),指线程处于进入等待状态,此时线程不占用任何资源,不增加时间限制。wait可以被notify和notifyAll函数唤醒(当然这两个同时也是Object的函数)。而sleep则是Thread类的一个函数,指线程被调用时,占着CPU不工作。此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。

1、函数


第一个区别是在对系统资源的占用上。

wait是Object类的一个函数(也就意味着所有对象都有这个函数),指线程处于进入等待状态,此时线程不占用任何资源,不增加时间限制。wait可以被notify和notifyAll函数唤醒(当然这两个同时也是Object的函数)。

而sleep则是Thread类的一个函数,指线程被调用时,占着CPU不工作。此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。

所以

  • sleep(100L)意思为:占用CPU,线程休眠100毫秒
  • wait(100L)意思为:不占用CPU,线程等待100毫秒

注意:wait和sleep最终都是调用native函数。


2、多线程


第二个区别是在多线程中对锁的处理上。(其实也是第一个区别的一个具体表现)

使用多线程就没法绕过同步问题,而wait和sleep对于同步锁也有不同的效果

(1)在使用上,调用Object的wait和notify函数前必须获取对象锁,即在synchronized(obj){...}代码块中。

(2)如果都在synchronized代码块中,wait(obj)函数可以释放锁,而sleep函数则不释放锁。

注意在wait释放锁这里有这样一个场景:

有两个线程,分别是A和B,在A线程中有如下代码:


synchronized(mLock){
     ...
     mLock.wait();
     ...
}
复制代码


这样在synchronized处获取对象锁,当执行到wait函数时,线程A进入等待状态,并且释放对象锁。

在B线程中有如下代码:


synchronized(mLock){
     ...
     mLock.notify();
     ...
}
复制代码


当线程A的wait函数释放锁时,B线程的synchronized获取了对象锁,开始执行代码。

当执行到notify函数时,唤醒A线程。但是这时由于B的synchronized代码块未执行完,所以未释放锁。所以先执行B线程notify后面的代码,B的synchronized代码执行完后释放锁,A线程获取锁并执行wait之后的代码。

(注意,如果有多个wait状态的object,notify函数只能唤醒其中一个,至于唤醒哪一个是由JVM决定的,而notifyAll则可以唤醒所有的)

让我们来测试一下,我们的测试代码如下:


Thread a = new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (mLock){
            Log.e("sss", "a 1");
            try {
                mLock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.e("sss", "a 2");
        }
    }
});
Thread b = new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (mLock){
            Log.e("sss", "b 1");
            try {
                mLock.notify();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Log.e("sss", "b 2");
        }
    }
});
a.start();
b.start();
复制代码


运行后,终端打印的日志如下:

12-14 18:50:12.909 22793-22824/com.example.testapplication E/sss: a 1 12-14 18:50:12.909 22793-22825/com.example.testapplication E/sss: b 1 12-14 18:50:12.909 22793-22825/com.example.testapplication E/sss: b 2 12-14 18:50:12.909 22793-22824/com.example.testapplication E/sss: a 2


这样我们就可以清楚的看到执行的前后顺序了,更容易理解上面提到的锁释放的时机了。


目录
相关文章
|
2天前
sleep()和wait()的区别
(1)wait()是Object的方法,sleep()是Thread类的方法 (2)wait()会释放锁,sleep()不会释放锁 (3)wait()要在同步方法或者同步代码块中执行,sleep()没有限制 (4)wait()要调用notify()或notifyall()唤醒,sleep()自动唤醒
12 5
|
6月前
|
Java
在多线程中sleep()和wait()的区别(详细)
在多线程中sleep()和wait()的区别(详细)
sleep () 和 wait () 的区别
sleep () 和 wait () 的区别
89 0
|
监控
Sleep()和wait()方法的区别
Sleep()和wait()方法的区别
136 0
|
Java 程序员
sleep 和 wait 的区别
Java 中,线程的 "sleep" 和 "wait" 方法区别
129 0
|
调度 C++
Thread.sleep(0) vs Thread.sleep(1) vs Thread.yield() vs Object.wait()
Thread.sleep(0) vs Thread.sleep(1) vs Thread.yield() vs Object.wait()
|
Java
java多线程中sleep和wait的4个区别,你知道几个?
sleep和wait的区别是面试中一个非常常见的问题,因为从表象来看,好像sleep和wait都能使线程处于阻塞状态,但是却有着本质上的却别。这篇文章就来好好分析一下。 整体的区别其实是有四个: 1、sleep是线程中的方法,但是wait是Object中的方法。 2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。 3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。 4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。 下面我们就根据这四个区别来分析。
299 0
java多线程中sleep和wait的4个区别,你知道几个?
线程 - wait & sleep 区别
线程 - wait & sleep 区别
119 0
|
监控
sleep 与 wait 区别
sleep 与 wait 区别
114 0