黑马程序员技术交流社区

标题: 线程基础问题 [打印本页]

作者: 张水荣    时间: 2012-7-18 20:55
标题: 线程基础问题
本帖最后由 张水荣 于 2012-7-18 21:26 编辑

请问wait()方法与sleep()方法的区别是什么?

作者: 康大玮    时间: 2012-7-18 21:01

这两者的施加者是有本质区别的.

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可以在
    任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }
   4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异


作者: 黑马罗坚    时间: 2012-7-18 21:07
wait() 方法  需要在同步块中 它的调用者必须是这个同步的锁  该线程会睡眠 并且释放锁 如果参数有设置long值则休眠该时间在醒来  或者当拥有该锁的其他线程调用notify()方法在醒来   醒来以后不会马上获取cpu的执行权 也不会获得锁 而是加入等待线程池中 跟别的线程一起抢夺执行权和锁 用wait时要注意死锁的问题  sleep  休眠指定的时间 但是不释放锁   休眠和wait都可以被别的线程踢醒  被提醒的线程会抛异常
作者: 陈欢    时间: 2012-7-18 21:20
1.sleep()使线程休眠一段时间,一段时间结束后,线程进入可执行状态,但并不是立即执行,只是在被

排程器调用的时候才执行。在休眠期间,并不释放所持有的“锁”;

2.wait()使线程休眠一段时间,若设置参数,时间到时,线程就自动进入可执行状态。若没有,则需要

notify()方法去调用。值得注意的是:wait()方法和notify()方法都时针对this对象的,调用wait()方法后,会释

放加在对象上的“锁”。


我理解大概就是这样的



可以参考下代码:

public class TestNotify {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

TestNotify testNotify = new TestNotify();

ThreadB b = testNotify.new ThreadB();

b.start();

System.out.println("b is start");

synchronized(b)

{

try

{

System.out.println("Waiting for b to complete");

b.wait(); // 暂时放弃对象锁,让主线程暂停,让ThreadB开始执行

}

catch(InterruptedException e)

{

e.printStackTrace();

}

System.out.println("Final Total is:"+b.total);

}

}

class ThreadB extends Thread{

int total;

public void run()

{

synchronized(this)

{

System.out.println("ThreadB is running");

for(int i=0;i<100;i++)

{

total+=i;

}

notify(); // 执行完毕,唤醒被暂停的线程

}

}

}

}

运行结果:b is start
Waiting for b to complete
ThreadB is running
Final Total is:4950
作者: 周玉龙    时间: 2012-7-18 21:43
java 线程中的sleep和wait有一个共同作用,停止当前线程任务运行,但他们存在一定的不同。
总体来说说有四个区别:
第一:出处不同,sleep方法来自Thread类,wait方法来自Object类。
第二:sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
第三:使用范围不一样,3、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()方法而产生
InterruptedException异常,效果以及处理方式同sleep()方法。

作者: 杨康    时间: 2012-7-18 21:48
wait()方法等待后不能自己唤醒,需要得到notify()提示后才能结束等待状态。
而sleep()方法可以自定义等待时间,当时间到了后,无论是否有外部唤醒,都是结束等待状态。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2