java线程中的sleep和wait有一个相同的作用是停止当前线程任务运行,但有区别之处,
(1)sleep方法属于Thread类中的方法,表示让一个线程进入睡眠状态,等待一定的时间后,自动醒来进入到可运行状态,而不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法后,并不会释放它所有的对象锁,也不会影响其他线程对象的运行。但在睡眠的过程中有可能被其他对象调用它的interrupt()产生InterruptException异常,如果程序不捕获该异常,线程就会异常终止 ,进入Terminated(程序停止)状态,如果程序捕获了该异常,则程序就会继续执行catch块及后边的代码。
sleep()方法是一个静态方法,它只对当前对象有效,通过o.sleep()让o对象进入sleep,它只会使当前线程睡眠而不是o线程。
(2)wait属于Object的成员方法,一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该线程,如果线程拥有某些对象的同步锁,则在调用了wait()后,该线程就会释放它的所有同步资源 ,而不限于这个被调用了wait()方法的对象。wait()方法也会在wait的过程中有可能被其他对象调用interrupt()方法而产生InterruptedException,处理方式与sleep方法相同。
notify()是释放对象的wait()方法而阻塞线程,这个释放是随机的,也就是不一定要释放哪个线程。
notifyAll() 也可起到类似作用,唯一的区别在于,调用 notifyAll() 方法将把因调用该对象的wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。但是这一对方法却必须在 synchronized方法或块中调用,因为只有在synchronized 方法或块中当前线程才占有锁,才有锁可以释放。
这里简述一下interrupt(),interrupt是中断。一个线程被调用interrupt()后,会影响到sleep、wait方法,同时方法内部会不断检查中断状态的值,若发现线程的状态被置为已中断,sleep、wait方法便会抛出InterruptedException异常。被中断的线程则将控制权交给了catch语句。interrupted方法是查询是否有“中断状态”这一标志 ,通常情况下这一标志未被设置,一旦调用了interrupt()方法,interrupt()就设置了这个标志 ,则所有当前正在阻塞的方法(由于wait、sleep方法引发的阻塞)都会立刻完成“跳出
阻塞状态、抛出InterruptedException异常,清除中断状态标志”这三个任务。
|