欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Thread.sleep/wait

程序员文章站 2022-07-14 16:16:13
...

jdk1.7

java.lang.Thread的一个静态方法sleep(long)

官方文档这样介绍:

  • 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. The thread does not lose ownership of any monitors.(使当前线程睡眠(临时停止运行)规定的时间,并且不会释放当前持有的资源(监视器、锁))
多线程之间的通信是通过锁实现的,说白了就是多个线程竞争共享资源的持有权,谁拿到手谁就能操作,没拿到的只能等持有者放弃再竞争。当线程中执行 obj.wait的时候就会放弃锁的持有,把资源让出去。但是静态方法Thread.sleep不会放弃持有的资源,直到被打断或者sleep的时间到。

下边一个例子验证wait的放弃资源和sleep的不放弃资源


public class TestSleep implements Runnable{
	/**
	 * 测试Thread.sleep(10000);不会释放资源
	 */
	public synchronized void testSource(){
		String name = Thread.currentThread().getName();
		for (int i = 0;i<10; i++) {
			try {
				if(name.equals("t-1")){
					System.out.println("线程【"+name+"]" + "等待10s" );
					// 第一段代码
					//Thread.sleep(5000);
					// 第二段代码
					this.wait(10000);
				}
				System.out.println("线程【"+name+"]" + "打印" + i);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public void run() {
		testSource();
	}
	public static void main(String[] args) throws Exception {
		TestSleep t1= new TestSleep();
		for (int i = 0; i < 10; i++) {
			Thread thread1 = new Thread(t1,"t-"+i);
			thread1.start();
		}
		
	}
}


代码内容很简单,创建10个线程,没个线程打印是个数字,当线程名称是t-1的时候等待/睡眠10s。

先测试wait,注释第一段代码,放开第二段代码,执行结果会发现,打印90多行数据,然后程序没个10s再打印一行,知道100行数据全都打印完。不管执行几次都是这样的结果,可能打印的顺序同,但最后执行完的肯定是t-1这个线程。这就说明,t-1这个线程wait的时候持有的对象锁已经放开,别的线程可以拿到进行使用。


放开第一段代码,注释第二段代码,测试sleep的不释放资源。结果显示,t-1获取到对象锁的时候就开始等待10s打印数据,不会释放对象锁,等到t-1的任务完成之后别的进程才能拿到对象锁进行打印工作。所有t-1的可能不是最后执行完的的。