一、二者的区别
- 这两个方法来自不一样的类分别是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便可安全地结束线程。html
须要注意的是,InterruptedException是线程本身从内部抛出的,并非interrupt()方法抛出的。对某一线程调用interrupt()时,若是该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。可是,一旦该线程进入到wait()/sleep()/join()后,就会马上抛出InterruptedException。java
waite()和notify()由于会对对象的“锁标志”进行操做,因此它们必须在synchronized函数或synchronized block中进行调用。若是在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译经过,但在运行时会发生illegalMonitorStateException的异常。安全
补充两个重要的方法:yield()和join()函数
yield方法 post
暂停当前正在执行的线程对象。 url
yield()方法是中止当前线程,让同等优先权的线程或更高优先级的线程有执行的机会。若是没有的话,那么yield()方法将不会起做用,而且由可执行状态后立刻又被执行。 spa
join方法是用于在某一个线程的执行过程当中调用另外一个线程执行,等到被调用的线程执行结束后,再继续执行当前线程。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,致使结果不可预测。 .net
说一下为何使用wait()方法时,通常是须要while循环而不是if?
while(!执行条件) { wait(); } .... if(!执行条件) { wait(); } ....
while会一直执行循环,直到条件知足,执行条件才会继续往下执行。if只会执行一次判断条件,不知足就会等待。这样就会出现问题。线程
咱们知道用notify() 和notifyAll()能够唤醒线程,通常咱们经常使用的是notifyAll(),由于notify(),只会随机唤醒一个睡眠线程,并不必定是咱们想要唤醒的线程。若是使用的是notifyAll(),唤醒全部的线程,那你怎么知道他想唤醒的是某个正在等待的wait()线程呢,若是用while()方法,就会再次判断条件是否是成立,知足执行条件了,就会接着执行,而if会直接唤醒wait()方法,继续往下执行,根本无论这个notifyAll()是否是想唤醒的是本身仍是别人,可能此时if的条件根本没成立。code
举个例子:
while去水果店买苹果,没有了,而后while就和水果店老板说,有水果的时候通知我,我先回去了。if也去水果店买苹果,没有了,而后if就和水果店老板说,有水果的时候通知我,我先回去了。过一段时间,水果店老板发短信告诉while和if,有水果了,while去一看,水果店只是进了香蕉,并非苹果,因此不是想要的水果,因而回去继续等水果店老板通知,而if根本就不看是否是本身想要的苹果,直接就叫老板送10斤水果过来,这样会致使你获得错误的结果。
参考文献: