线程中sleep和wait的区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程中sleep和wait的区别相关的知识,希望对你有一定的参考价值。
线程中sleep和wait的区别如下:一,首先二者的不同点:
1.这两个方法来自不同的类分别是Thread和Object。首先对于sleep()方法,要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
2.sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备。获取对象锁进入运行状态。
3.最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)
比如:
synchronized(x)
x.notify()
//或者wait()
4.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
举例说明如下:
1.首先我们先看sleep中的构造函数
sleep(long millis) Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
sleep(long millis, int nanos) Causes the currently executing thread to sleep (cease execution) for the specified number of milliseconds plus the specified number of nanoseconds, subject to the precision and accuracy of system timers and schedulers.
sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。
另外注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,通过t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程
2.wait方法
void wait(long timeout)
Causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.
void wait(long timeout, int nanos)
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.
wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生
InterruptedException,效果以及处理方式同sleep()方法
二,最后二者的共同点:
1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。
如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep /join,则线程B会立刻抛出InterruptedException,在catch() 中直接return即可安全地结束线程。
需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。
以上就是线程中sleep和wait的区别。 参考技术A 还有用法的上的不同是:sleep(milliseconds)可以用时间指定来使他自动醒过来,如果时间不到你只能调用interreput()来强行打断;wait()可以用notify()直接唤起.第二种解释:sleep是Thread类的静态方法。sleep的作用是让线程休眠制定的时间,在时间到达时恢复,也就是说sleep将在接到时间到达事件事恢复线程执行,例如:try
System.out.println("I'm
going
to
bed");
Thread.sleep(1000);
System.out.println("I
wake
up");catch(IntrruptedException
e)
wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者,例如://Thread
1try
obj.wait();//suspend
thread
until
obj.notify()
is
calledcatch(InterrputedException
e)
第三种解释:这两者的施加者是有本质区别的.
sleep()是让某个线程暂停运行一段时间,其控制范围是由当前线程决定,也就是说,在线程里面决定.好比如说,我要做的事情是
"点火->烧水->煮面",而当我点完火之后我不立即烧水,我要休息一段时间再烧.对于运行的主动权是由我的流程来控制.
而wait(),首先,这是由某个确定的对象来调用的,将这个对象理解成一个传话的人,当这个人在某个线程里面说"暂停!",也是
thisOBJ.wait(),这里的暂停是阻塞,还是"点火->烧水->煮饭",thisOBJ就好比一个监督我的人站在我旁边,本来该线
程应该执行1后执行2,再执行3,而在2处被那个对象喊暂停,那么我就会一直等在这里而不执行3,但正个流程并没有结束,我一直想去煮饭,但还没被允许,
直到那个对象在某个地方说"通知暂停的线程启动!",也就是thisOBJ.notify()的时候,那么我就可以煮饭了,这个被暂停的线程就会从暂停处
继续执行.
其实两者都可以让线程暂停一段时间,但是本质的区别是一个线程的运行状态控制,一个是线程之间的通讯的问题
在java.lang.Thread类中,提供了sleep(),
而java.lang.Object类中提供了wait(),
notify()和notifyAll()方法来操作线程
sleep()可以将一个线程睡眠,参数可以指定一个时间。
而wait()可以将一个线程挂起,直到超时或者该线程被唤醒。
wait有两种形式wait()和wait(milliseconds).
sleep和wait的区别有:
1,这两个方法来自不同的类分别是Thread和Object
2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用 参考技术B 1、这两个方法来自不同的类分别是Thread和Object
2、最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)
synchronized(x)
x.notify()
//或者wait()
4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
多线程中sleep和wait的区别,以及多线程的实现方式及原因,定时器--Timer
1. Java中sleep和wait的区别
① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。
sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。
② 锁: 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。
Thread.sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。
③ 使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。
synchronized(x){
x.notify()
//或者wait()
}
2.可能在面试的时候面试官会问你java实现多线程的方式有哪些,你可能会知道java要提供继承Thread类和实现runnable接口这两种方式来实现线程,但是如果问为什么这样设计呢?
首先说一下,我们知道java的集成只能是单继承,不能多集成,这样的话就会有缺陷,比如想增加一个功能的时候必须要去修改基类。而实现runnable接口的这种方式可以很好的解决java不能多继承导致的缺陷。这是第一个原因。
再说第二个,我们知道实现runnable接口的方式代码的写法是这样的:new Thread(new runnable(){ public void run(){ ....}})。在这种情况下我们可以看到其实整个的runnable对象中的代码可以被多个Thread对象实例所使用共享,这样就可以解决一个多个线程处理同一资源的情况。做到了线程安全。在这里我觉着有必要通过一个代码的方式来解释一下第二个优点是如何实现的。
3.首先来说一下Timer是怎么工作的,Timer 是按照一定的时间段或者一个时间点根据定时的定时任务进行执行的。
Timer这个java提供的定时器有如下的特点:
① 他是一个单线程的,也就是你启动一个Timer定时器就是启动了一个线程。
② Timer定时器默认的情况下不是守护线程,但是可以通过构造参数设置为守护线程,守护线程在没有其他线程的情况下自己会挂掉。
③ 使用Timer定时器的时候 要跟一个TimerTask定时任务结合来使用。而且TimerTask其实底层就是一个队列,在TimerTask中增加的任务会在定时器这个线程里面挨个的执行。TimerTask也有自己的cannel取消等方法。
④ TimerTask中的run方法无法抛出,所以要进行try catch捕获,如果其中任何一个任务发生异常没有被捕获,则其他任务也将被终止。
我们看到TImer定时器这个类有两个schedule方法。其中都有的就是一个TimerTask这个任务。我对这两个方法进行了一个总结:
Timer是一个单独的线程,从第152行我们就可以看到,我们可以设置线程的名称,可以设置是否是守护线程,然后调用start方法定时器就起作用了。但是并不会立即执行。线程调用start后也不会立即执行,这在上一篇中已经有说到了,他其实是把当前的线程示例放到了一个线程组中等待被执行。
哪我们就看他是如何调度的也就是schdule是如何执行的呢。
这里我们补充一下,queue是一个TaskQueue
以上是关于线程中sleep和wait的区别的主要内容,如果未能解决你的问题,请参考以下文章