Java 中的sleep()和wait()的区别

对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

在调用sleep()方法的过程中,线程不会释放对象锁

而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备,获取对象锁进入运行状态。

 

package Demo0422TestSynchronized;

/**
 * java中的sleep()和wait()的区别
 * 
 * @author Hongten
 * @date 2013-12-10
 */
public class TestD {

	public static void main(String[] args) {
		new Thread(new Thread1(),"线程1").start();
		try {
			
			Thread.sleep(5000);
			System.out.println(Thread.currentThread().getName() + "****睡5秒****");
		} catch (Exception e) {
			e.printStackTrace();
		}
		new Thread(new Thread2(),"线程2").start();
	}

	private static class Thread1 implements Runnable {
		@Override
		public void run() {
			synchronized (TestD.class) {
				System.out.println("enter thread1...");
				System.out.println("thread1 is waiting...");
				try {
					// 调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池
					TestD.class.wait();
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("thread1 is going on ....");
				System.out.println("thread1 is over!!!");
				TestD.class.notifyAll();
			}
		}
	}

	private static class Thread2 implements Runnable {
		@Override
		public void run() {
			synchronized (TestD.class) {
				System.out.println("enter thread2....");
				System.out.println("thread2 is sleep....");
				// 只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
				System.out.println(Thread.currentThread().getName()+"将会唤醒另一个线程");
				TestD.class.notify();
				// ==================
				// 区别
				// 如果我们把代码:TestD.class.notify();给注释掉,即TestD.class调用了wait()方法,但是没有调用notify()
				// 方法,则线程永远处于挂起状态。
				try {
					// sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,
					// 但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
					// 在调用sleep()方法的过程中,线程不会释放对象锁。
					Thread.sleep(5000);
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("thread2 is going on....");
				System.out.println("thread2 is over!!!");
				System.out.println(Thread.currentThread().getName() + "即将结束, 结束之前再睡10秒   后进入等待状态");
		
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				try {
					TestD.class.wait();
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
	}
}

程序运行结果:

enter thread1...
thread1 is waiting...
main****睡5秒****
enter thread2....
thread2 is sleep....
线程2将会唤醒另一个线程
thread2 is going on....
thread2 is over!!!
线程2即将结束, 结束之前再睡10秒
thread1 is going on ....
thread1 is over!!!

 

 

 

等待唤醒机制与synchronized

所谓等待唤醒机制本篇主要指的是notify/notifyAll和wait方法,在使用这3个方法时,必须处于synchronized代码块或者synchronized方法中,否则就会抛出IllegalMonitorStateException异常,这是因为调用这几个方法前必须拿到当前对象的监视器monitor对象,也就是说notify/notifyAll和wait方法依赖于monitor对象,在前面的分析中,我们知道monitor 存在于对象头的Mark Word 中(存储monitor引用指针),而synchronized关键字可以获取 monitor ,这也就是为什么notify/notifyAll和wait方法必须在synchronized代码块或者synchronized方法调用的原因。

synchronized (obj) {
       obj.wait();
       obj.notify();
       obj.notifyAll();         
 }

 

需要特别理解的一点是,与sleep方法不同的是wait方法调用完成后,线程将被暂停,但wait方法将会释放当前持有的监视器锁(monitor),直到有线程调用notify/notifyAll方法后方能继续执行,而sleep方法只让线程休眠并不释放锁。同时notify/notifyAll方法调用后,并不会马上释放监视器锁,而是在相应的synchronized(){}/synchronized方法执行结束后才自动释放锁。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值