(一)线程管理_4---线程休眠和恢复

线程休眠和恢复

在有的时候需要将线程暂时停止执行,在一段时间后恢复线程,让其继续执行;比如一个线程每隔一分钟执行一次状态检查,那么余下的时间我们希望它能够让出CPU time,什么也不做,最大的减少资源的浪费;在线程恢复后,再给予CPU time,让其继续执行;为了满足这样一个需求,可以调用Thread类的sleep()方法达到这个目的;

Thread.sleep(millis) ,另外还可以使用TimeUnit类进行休眠,如TimeUnit.SECONDS.sleep(millis) ;

动手实验

public class FileClock implements Runnable{
    @Override
    public void run() {
        /*
            每次循环打印一个时间,模拟一个任务,之后休眠1毫秒,
            在sleep时,如果被中断,将会抛出InterruptedException
         */
        for (int i = 0; i < 10; i++) {
            System.out.printf("%s\n",new Date());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                System.out.printf("The FileClock has been interrupted.");
            }
        }
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new FileClock());
        thread.start();

        /*
            主线程等待5毫秒
         */
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /*
            唤醒FileClock线程
         */
        thread.interrupt();
    }
}

一次运行结果:

Thu Oct 30 23:09:25 CST 2014
Thu Oct 30 23:09:26 CST 2014
Thu Oct 30 23:09:27 CST 2014
Thu Oct 30 23:09:28 CST 2014
Thu Oct 30 23:09:29 CST 2014
The FileClock has been interrupted.Thu Oct 30 23:09:30 CST 2014
Thu Oct 30 23:09:31 CST 2014
Thu Oct 30 23:09:32 CST 2014
Thu Oct 30 23:09:33 CST 2014
Thu Oct 30 23:09:34 CST 2014


首先,fileclock线程开始执行,然后主线程等待,在fileclock还没结束,主线程执行对fileclock执行了interrupt()方法,注意这里,上节记录的这个方法会有effect以及它和IsInterrupt的区别,这个方法设置线程的中断标记,那么此时有一个问题:如果此时fileclock刚还没有进入sleep方法,此时该怎么执行?会不会当再次进入sleep时直接中断进入catch块,还是执行休眠完后中断? 如果此时fileclock线程正在休眠,显然会直接中断被catch块捕获,这个就毫无疑问了,那么下面就上面这个疑惑进行一个实验,主线程启动子线程后,调用interrupt,设置子线程已经中断,故意让子线程一定在主线程执行了interrupt之后,子线程才调用sleep,已观察执行过程,那么下面开始

public class InterruptTest implements Runnable{
    @Override
    public void run() {
        /*
            while的目的是保证在主线执行完thread.interrupt()方法后,才结束while
            执行下面的sleep,可以通过结果的两个输出看出(Before,After)
         */
        long start=System.currentTimeMillis();
        while((System.currentTimeMillis()-start)<5000){
            //empty
        }
        System.out.printf("After:Thread will be sleep.\n");
        try {
            TimeUnit.SECONDS.sleep(200);
            System.out.printf("After sleep.\n");
        } catch (InterruptedException e) {
            System.out.printf("Interrupted.");
        }
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new InterruptTest());
        thread.start();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        thread.interrupt();
        System.out.printf("Before:Main execute thread.interrupt().\n");
    }
}
执行结果:

Before:Main execute thread.interrupt().
After:Thread will be sleep.
Interrupted.

显然 sleep语句后面的“After sleep"并没有输出,从输出的结果可以看到子线程也并没有去休眠200毫秒,而至直接中断被catch捕获;

那么可以得出结论:当一个线程的被设置了中断状态,如调用了interrupt(),那么该线程在执行到sleep时,将会立即被中断捕获;


要点

还是要理解线程维护的中断状态和Thread.interrupt()之后线程如何执行;

此外 Thread.yield()方法也能是线程暂时放弃cpu,但是JVM并不保证线程的这个请求的响应;通常,仅仅是作为debug的目的;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值