Java Thread sleep和wait的区别

时间:2022-06-16 15:37:13

我们在编写Java线程程序的时候,经常忽略sleep 和 wait方法的区别,导致一些非常棘手的问题,因此了解这两种方法区别有助于我们编写出更加优质的程序。

区别: 

                                            sleep()                                        wait()
 sleep为Thread类的方法,用来控制线程自身流程  wait为object类的方法,主要用于线程间通信
 sleep()睡眠时,保持对象锁  wait()睡眠时,释放对象锁,使当前拥有该对象锁的线程等待,直到其他线程调用notify唤醒(备注:也可以使用超时唤醒)
 不能访问同步代码块  能够访问同步代码块

代码:

[java] view plaincopy
  1. package com.jony.test;  
  2.   
  3. public class ThreadTest implements Runnable {  
  4.     int number = 10;  
  5.   
  6.     public void firstMethod() throws Exception {  
  7.         System.out.println("first");  
  8.         System.out.println(Thread.currentThread());  
  9.         System.out.println(this);  
  10.         synchronized (this) {  
  11.             number += 100;  
  12.             System.out.println(number);  
  13.             notify();  
  14.         }  
  15.     }  
  16.   
  17.     public void secondMethod() throws Exception {  
  18.         System.out.println("second");  
  19.         System.out.println(Thread.currentThread());  
  20.         System.out.println(this);  
  21.         synchronized (this) {  
  22.             /* 
  23.              * sleep()睡眠时,保持对象锁,仍然占有该锁; 而wait()睡眠时,释放对象锁。 因此: 
  24.              * (1)sleep不会访问其他同步代码块  
  25.              * (2)wait 则会访问其他同步代码块  
  26.              * (休息2S,阻塞线程) 
  27.              * 以验证当前线程对象的锁被占用时, 是否可以访问其他同步代码块 
  28.              */  
  29.             //Thread.sleep(2000);  
  30.             //this.wait(2000);//只能在同步代码块中调用wait方法  
  31.             this.wait();  
  32.             System.out.println("Before: " + number);  
  33.             number *= 200;  
  34.             System.out.println("After: " + number);  
  35.   
  36.         }  
  37.     }  
  38.   
  39.     @Override  
  40.     public void run() {  
  41.         try {  
  42.             firstMethod();  
  43.         } catch (Exception e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.     }  
  47.   
  48.     public static void main(String[] args) throws Exception {  
  49.         ThreadTest threadTest = new ThreadTest();  
  50.         Thread thread = new Thread(threadTest);  
  51.         System.out.println(Thread.currentThread());  
  52.         //thread.run(); // 不会创建新线程,直接调用run方法  
  53.         thread.start();// 开始执行该线程(创建一个新线程),由Java虚拟机调用该线程的run方法  
  54.         //Thread.sleep(1000);  
  55.         threadTest.secondMethod();  
  56.     }  

1、这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。

sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。


2、最主要sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

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不需要捕获异常