Java中wait与sleep的区别、示例

时间:2023-01-12 15:34:11


区别:

    1、这两个方法来自不同的类, wait来自Object类,而sleep来自Thread类;

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

  3、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围。)

  synchronized( obj ){
   obj.notify()   // 或者obj.wait()

  }

  4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常。


 扩充阅读:

  java 线程中的sleep和wait有一个共同作用,停止当前线程任务运行,但他们存在一定的不同,首先我们先看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线程。


 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()方法。



Sleep、Wait与Notify的协作例子 (生产者与消费者):

消费者:

import java.util.List;

/**
* @Title: Consumer.java
* @Package
* @Description: 消费者
* @author Mr.Simple bboyfeiyu@gmail.com
* @date May 25, 2013 2:31:48 PM
* @version V1.0
*/
public class Consumer implements Runnable {

private List<Object> mProducts = null ;
private int mCount = 0;

/**
* 构造函数
* @param products
*/
public Consumer(List<Object> products){
mProducts = products ;
}


/**
* 注意此处 : wait好notify都必须在synchronized控制范围内
* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
while( true ){
synchronized (mProducts) {
// 产品消费完,则进入等待状态
while( mProducts.size() == 0 ){
try{
// 没有产品消费,则等待生产者生产,消费者进入等待状态。
mProducts.wait() ;
}catch(Exception e){
e.printStackTrace() ;
}
} // end of while

try {
// 当前线程睡眠1秒,必须要try和catch。
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mProducts.remove(0);
// notify也必须在同步锁控制里面
mProducts.notify();
System.out.println("我是消费者,我吃了 " + (++mCount) + "个包子。");

} // end of synchronized

}
}// end of run

}

生产者 : 

import java.util.List;

/**
* @Title: Producer.java
* @Package
* @Description:
* @author Mr.Simple bboyfeiyu@gmail.com
* @date May 25, 2013 2:50:36 PM
* @version V1.0
*/
public class Producer implements Runnable {

private List<Object> mProducts = null;
private int mCount = 0;
private int mMaxCount = 5;

Producer(List<Object> products){
mProducts = products ;
}

/**
* 注意此处 : wait好notify都必须在synchronized控制范围内
* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
while( true ){
synchronized (mProducts) {
// 当生产到了最大库存的时候进入等待状态,让消费者消费产品
while( mProducts.size() > mMaxCount){
try{
mProducts.wait() ;
}catch(Exception e){
e.printStackTrace() ;
}
} // end of while

// 生产满最大库存之前继续生产产品
try {
// 当前线程睡眠1秒,必须要try和catch。
Thread.sleep( 1000 );
} catch (InterruptedException e) {
e.printStackTrace();
}

mProducts.add(new Object());
// nofity也必须在同步控制范围内
mProducts.notify();
System.out.println("我是生产者,我生产了 " + (++mCount) + "个包子。");

} // end of synchronized
}
}// end of run

}

场景类 :

import java.util.ArrayList;
import java.util.List;

/**
* @Title: Client.java
* @Package
* @Description: 场景类
* @author Mr.Simple bboyfeiyu@gmail.com
* @date May 25, 2013 2:58:20 PM
* @version V1.0
*/
public class MultiThreadClient {

private List<Object> mProducts = new ArrayList<Object>();
public static int MAXCOUNT = 5;

/**
*
* @Title: getProducts
* @Description: 获得产品容器
* @return List<Object>
* @throws
*/
public List<Object> getProducts(){
return this.mProducts ;
}

// main
public static void main(String[] args){
// 客户程序
MultiThreadClient clt = new MultiThreadClient();
// 启动一个消费者,将Client的mProducts引用传递给消费者,启动该线程
new Thread(new Consumer( clt.getProducts() )).start();
// 生产者
new Thread(new Producer( clt.getProducts() )).start();
}
}


结果 :
Java中wait与sleep的区别、示例