• Java中wait和sleep方法的区别


    1、两者的区别

    • 这两个方法来自不同的类分别是Thread和Object  
    • 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁)。  
    • wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)  
    • sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常  
    • sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。  
    • 注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,通过t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程  
    •  wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生  

    如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。

    需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到wait()/sleep()/join()后,就会立刻抛出InterruptedException。

    waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生illegalMonitorStateException的异常。

    补充两个重要的方法:yield()和join()

    yield方法  

    暂停当前正在执行的线程对象。  

    yield()方法是停止当前线程,让同等优先权的线程或更高优先级的线程有执行的机会。如果没有的话,那么yield()方法将不会起作用,并且由可执行状态后马上又被执行。   

    join方法是用于在某一个线程的执行过程中调用另一个线程执行,等到被调用的线程执行结束后,再继续执行当前线程。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。  

    说一下为什么使用wait()方法时,一般是需要while循环而不是if?

    复制代码
    while(!执行条件) {
        wait();
    }
    ....
    
    
    if(!执行条件) {
        wait();
    }
    ....
    复制代码

    while会一直执行循环,直到条件满足,执行条件才会继续往下执行。if只会执行一次判断条件,不满足就会等待。这样就会出现问题。

    我们知道用notify() 和notifyAll()可以唤醒线程,一般我们常用的是notifyAll(),因为notify(),只会随机唤醒一个睡眠线程,并不一定是我们想要唤醒的线程。如果使用的是notifyAll(),唤醒所有的线程,那你怎么知道他想唤醒的是某个正在等待的wait()线程呢,如果用while()方法,就会再次判断条件是不是成立,满足执行条件了,就会接着执行,而if会直接唤醒wait()方法,继续往下执行,根本不管这个notifyAll()是不是想唤醒的是自己还是别人,可能此时if的条件根本没成立。

    举个例子:

    while去水果店买苹果,没有了,然后while就和水果店老板说,有水果的时候通知我,我先回去了。if也去水果店买苹果,没有了,然后if就和水果店老板说,有水果的时候通知我,我先回去了。过一段时间,水果店老板发短信告诉while和if,有水果了,while去一看,水果店只是进了香蕉,并不是苹果,所以不是想要的水果,于是回去继续等水果店老板通知,而if根本就不看是不是自己想要的苹果,直接就叫老板送10斤水果过来,这样会导致你得到错误的结果。

    参考文献:

    Java中wait 和sleep 方法比较

    JAVA—sleep()和wait()的区别

    java中的sleep()和wait()的区别

  • 相关阅读:
    Mac sublime text4 修改选中行背景色
    转|java反射方法和使用详解
    浅析Java8中default关键字
    HashMap知识点梳理、常见面试题和源码分析
    100道运维常见面试题
    Python遇到的问题和解决方法汇总
    Git分支管理规范
    29个运维经典面试题
    运维必备技能
    PMP:挣值管理(PV、EV、AC、SV、CV、SPI、CPI)的记忆方法
  • 原文地址:https://www.cnblogs.com/cyl048/p/8612453.html
Copyright © 2020-2023  润新知