概要
本章, 会对 Thread 中 sleep()方法进行介绍. 涉及到的内容包括:
sleep()介绍
sleep()示例
sleep() 与 wait()的比较
一. sleep()介绍
sleep() 定义在 Thread.java 中.
sleep() 的作用是让当前线程休眠, 即当前线程会从 "运行状态" 进入到 "休眠 (阻塞) 状态".sleep()会指定休眠时间, 线程休眠的时间会大于 / 等于该休眠时间; 在线程重新被唤醒时, 它会由 "阻塞状态" 变成 "就绪状态", 从而等待 CPU 的调度执行.
二. sleep()示例
下面通过一个简单示例演示 sleep()的用法.
- // SleepTest.java 的源码
- class ThreadA extends Thread{
- public ThreadA(String name){
- super(name);
- }
- public synchronized void run() {
- try {
- for(int i=0; i <10; i++){
- System.out.printf("%s: %d\n", this.getName(), i);
- // i 能被 4 整除时, 休眠 100 毫秒
- if (i%4 == 0)
- Thread.sleep(100);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- public class SleepTest{
- public static void main(String[] args){
- ThreadA t1 = new ThreadA("t1");
- t1.start();
- }
- }
运行结果:
- t1: 0
- t1: 1
- t1: 2
- t1: 3
- t1: 4
- t1: 5
- t1: 6
- t1: 7
- t1: 8
- t1: 9
结果说明:
程序比较简单, 在主线程 main 中启动线程 t1.t1 启动之后, 当 t1 中的计算 i 能被 4 整除时, t1 会通过 Thread.sleep(100)休眠 100 毫秒.
三. sleep() 与 wait()的比较
我们知道, wait()的作用是让当前线程由 "运行状态" 进入 "等待 (阻塞) 状态" 的同时, 也会释放同步锁. 而 sleep()的作用是也是让当前线程由 "运行状态" 进入到 "休眠 (阻塞) 状态".
但是, wait()会释放对象的同步锁, 而 sleep()则不会释放锁.
下面通过示例演示 sleep()是不会释放锁的.
- // SleepLockTest.java 的源码
- public class SleepLockTest{
- private static Object obj = new Object();
- public static void main(String[] args){
- ThreadA t1 = new ThreadA("t1");
- ThreadA t2 = new ThreadA("t2");
- t1.start();
- t2.start();
- }
- static class ThreadA extends Thread{
- public ThreadA(String name){
- super(name);
- }
- public void run(){
- // 获取 obj 对象的同步锁
- synchronized (obj) {
- try {
- for(int i=0; i <10; i++){
- System.out.printf("%s: %d\n", this.getName(), i);
- // i 能被 4 整除时, 休眠 100 毫秒
- if (i%4 == 0)
- Thread.sleep(100);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
运行结果:(mynote: 只有两种结果, 要么 t1 先执行完, 要么 t2 先执行完)
- t1: 0
- t1: 1
- t1: 2
- t1: 3
- t1: 4
- t1: 5
- t1: 6
- t1: 7
- t1: 8
- t1: 9
- t2: 0
- t2: 1
- t2: 2
- t2: 3
- t2: 4
- t2: 5
- t2: 6
- t2: 7
- t2: 8
- t2: 9
结果说明:
主线程 main 中启动了两个线程 t1 和 t2.t1 和 t2 在 run()会引用同一个对象的同步锁, 即 synchronized(obj). 在 t1 运行过程中, 虽然它会调用 Thread.sleep(100); 但是, t2 是不会获取 CPU 执行权的. 因为, t1 并没有释放 "obj 所持有的同步锁"!
注意, 若我们注释掉 synchronized (obj)后再次执行该程序, t1 和 t2 是可以相互切换的. 下面是注释调 synchronized(obj) 之后的源码:
- // SleepLockTest.java 的源码(注释掉 synchronized(obj))
- public class SleepLockTest{
- private static Object obj = new Object();
- public static void main(String[] args){
- ThreadA t1 = new ThreadA("t1");
- ThreadA t2 = new ThreadA("t2");
- t1.start();
- t2.start();
- }
- static class ThreadA extends Thread{
- public ThreadA(String name){
- super(name);
- }
- public void run(){
- // 获取 obj 对象的同步锁
- // synchronized (obj) {
- try {
- for(int i=0; i <10; i++){
- System.out.printf("%s: %d\n", this.getName(), i);
- // i 能被 4 整除时, 休眠 100 毫秒
- if (i%4 == 0)
- Thread.sleep(100);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- // }
- }
- }
- }
其中一种运行结果:
- t1: 0
- t2: 0
- t1: 1
- t1: 2
- t2: 1
- t2: 2
- t2: 3
- t2: 4
- t1: 3
- t1: 4
- t2: 5
- t2: 6
- t1: 5
- t1: 6
- t1: 7
- t1: 8
- t2: 7
- t2: 8
- t1: 9
- t2: 9
来源: http://www.bubuko.com/infodetail-2825330.html