黑马程序员技术交流社区

标题: wait(milliseconds)和sleep(milliseconds)的不同? [打印本页]

作者: 夏天那抹蓝╮    时间: 2013-9-6 23:03
标题: wait(milliseconds)和sleep(milliseconds)的不同?
本帖最后由 夏天那抹蓝╮ 于 2013-9-8 16:26 编辑

wait(milliseconds)和sleep(milliseconds)的不同是什么?
wait(milliseconds)还需要唤醒吗?

作者: Bad_Boy    时间: 2013-9-6 23:06
sleep():调用这个方法的线程主动让出CPU,CPU去执行其他线程,在sleep指定的时间过后,CPU才会回来继续执行此线程,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使让出了CPU,其他线程也无法执行。
wait():在一个已经进入同步锁的的线程内,让自己暂时让出同步锁,让其他正在等待同步锁的线程,得到同步锁并执行,只有其他线程调用了notify()方法,调用wait()方法的线程就会解除wait状态和程序可以再一次得到同步锁后继续向下执行。
作者: 李锡碧    时间: 2013-9-6 23:21
1、sleep来自Thread类,和wait来自Object类。sleep是Thread的静态类方法,谁调用的谁sleep。
2、sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。
3、使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用。
   而sleep可以在任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }
4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常


作者: 辛春鹏    时间: 2013-9-7 07:42

帮助手册写的很详细的。
wait

public final void wait()
                throws InterruptedException
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。
sleep

public static void sleep(long millis,
                         int nanos)
                  throws InterruptedException
在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。
参数:
millis - 以毫秒为单位的休眠时间。
nanos - 要休眠的另外 0-999999 纳秒。
而且wait是Object类中的方法。sleep是Thread类中的方法。
作者: lonely_zb    时间: 2013-9-8 03:10
wait(milliseconds) 是需要去手动唤醒它的
sleep 是自动唤醒的,沉睡了指定时间后,程序自动唤醒,继续往下执行>
作者: hmwudizl91zl    时间: 2013-9-8 17:29
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。)
sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。
对于wait的讲解一定要配合例子代码来说明,才显得自己真明白。
  1. package com.huawei.interview;

  2. publicclass MultiThread {

  3.     /**
  4.      * @paramargs
  5.      */
  6.     public static voidmain(String[] args) {
  7.        // TODO Auto-generated method stub
  8.        new Thread(newThread1()).start();
  9.        try {
  10.            Thread.sleep(10);
  11.        } catch (InterruptedException e) {
  12.            // TODO Auto-generated catchblock
  13.            e.printStackTrace();
  14.        }
  15.        new Thread(newThread2()).start();   
  16.     }
  17.     private static classThread1implements Runnable
  18.     {
  19.       @Override
  20.        public void run() {
  21.            // TODO Auto-generated methodstub
  22. //由于这里的Thread1和下面的Thread2内部run方法要用同一对象作为监视器,我们这里不能用this,因为在Thread2里面的this和这个Thread1的this不是同一个对象。我们用MultiThread.class这个字节码对象,当前虚拟机里引用这个变量时,指向的都是同一个对象。
  23. synchronized (MultiThread.class){
  24. System.out.println("enterthread1...");
  25. System.out.println("thread1is waiting");
  26.     try {
  27.            //释放锁有两种方式,第一种方式是程序自然离开监视器的范围,也就是离开了synchronized关键字管辖的代码范围,另一种方式就是在synchronized关键字管辖的代码内部调用监视器对象的wait方法。这里,使用wait方法释放锁。
  28.         MultiThread.class.wait();
  29.               } catch(InterruptedException e) {
  30.                   // TODO Auto-generatedcatch block
  31.                   e.printStackTrace();
  32.               }
  33.             
  34.               System.out.println("thread1is going on...");
  35.               System.out.println("thread1is being over!");      
  36.            }
  37.        }
  38.       
  39.     }
  40.    
  41.     private static classThread2implements Runnable
  42.     {

  43.        @Override
  44.        public void run() {
  45.            // TODO Auto-generated methodstub
  46.            synchronized (MultiThread.class){
  47.          
  48.               System.out.println("enterthread2...");
  49.                            System.out.println("thread2notify other thread can release wait status..");
  50. //由于notify方法并不释放锁,即使thread2调用下面的sleep方法休息了10毫秒,但thread1仍然不会执行,因为thread2没有释放锁,所以Thread1无法得不到锁。
  51.                MultiThread.class.notify();
  52.             
  53.               System.out.println("thread2is sleeping ten millisecond...");
  54.               try {
  55.                   Thread.sleep(10);
  56.               } catch (InterruptedExceptione) {
  57.                   // TODO Auto-generatedcatch block
  58.                   e.printStackTrace();
  59.               }
  60.             
  61.               System.out.println("thread2is going on...");
  62.               System.out.println("thread2is being over!");
  63.             
  64.            }
  65.        }
  66.       
  67.     }  

  68. }
复制代码

作者: 杨彬    时间: 2013-9-9 13:49
sleep是根据传入值得大小决定放弃执行权的时间长短,sleep后不一定马上获取执行权
wait是需要唤醒后才能获取执行权




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