Java 多线程基础(七)线程休眠 sleep
一、线程休眠 sleep
sleep() 方法定义在Thread.java中,是 static 修饰的静态方法。
sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间;在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态”,从而等待cpu的调度执行。
二、sleep示例
public classSleepTest {private static Object obj = newObject();public static voidmain(String[] args) {
Thread t1= new MyThread("t1");t1.start();
}static class MyThread extendsThread{publicMyThread(String name) {super(name);
}public voidrun() {synchronized(obj) {try{for(int i = 0;i < 5;i++) {
System.out.println(Thread.currentThread().getName()+ "--" +i);if (i % 4 == 0)
Thread.sleep(1000);//i能被4整除时,休眠1秒
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
//运行结果
t1--0t1--1t1--2t1--3t1--4
说明:
在主线程main中启动线程t1。t1启动之后,当t1中的计算i能被4整除时,t1会通过Thread.sleep(100)休眠100毫秒。
三、sleep(long millis) 与 wait(long timeout)
我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
但是,wait() 会释放对象的同步锁,而 sleep() 则不会释放锁。
通过下面的代码,演示 sleep() 不会释放锁的:
public classSleepTest {private static Object obj = newObject();public static voidmain(String[] args) {
Thread t1= new MyThread("t1");
Thread t2= new MyThread("t2");
t1.start();
t2.start();
}static class MyThread extendsThread{publicMyThread(String name) {super(name);
}public voidrun() {synchronized(obj) {try{for(int i = 0;i < 5;i++) {
System.out.println(Thread.currentThread().getName()+ "--" +i);Thread.sleep(1000);//休眠1秒
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
//执行结果
t1--0t1--1t1--2t1--3t1--4t2--0t2--1t2--2t2--3t2--4
说明:
主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,虽然它会调用Thread.sleep(1000) 进入休眠状态;但是,t2是不会获取CPU执行权的。因为,t1并没有释放“obj所持有的同步锁”!
注意,若我们注释掉 synchronized (obj) 后再次执行该程序,t1和t2是可以相互切换执行的,原因是:在没有同步锁的情况下,当一个线程进入“休眠(阻塞)状态“时,会放弃CPU的执行权,另一个线程就会获取CPU执行权。
通过下面的代码,演示 wait() 会释放锁的:
public classSleepTest {private static Object obj = newObject();public static voidmain(String[] args) {
Thread t1= new MyThread("t1");
Thread t2= new MyThread("t2");
t1.start();
t2.start();
}static class MyThread extendsThread{publicMyThread(String name) {super(name);
}public voidrun() {synchronized(obj) {try{for(int i = 0;i < 5;i++) {
System.out.println(Thread.currentThread().getName()+ "--" +i);
obj.wait(1000);//等待1秒
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
//执行结果
t1--0t2--0t1--1t2--1t2--2t1--2t2--3t1--3t2--4t1--4
说明:
主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,调用 obj.wait(1000) 进入等待状态,释放同步锁;此时,t2会获取CPU执行权的。