线程异常分析

阅读:229

目录介绍

  • 01.如何捕获run方法异常
  • 02.sleep方法为何需要捕获异常
  • 03.sleep(0)作用是什么

02.sleep方法为何需要捕获异常

  • 先来看一下下面代码
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

  • 然后看一下源码
    • 从这里可以看出,当millis为0的时候,并且线程调用了interrupted方法,如果使用sleep则会抛出异常InterruptedException,所以需要捕获一下。
    • sleep方法添加了锁
    public static void sleep(long millis) throws InterruptedException {
        Thread.sleep(millis, 0);
    }
    
    public static void sleep(long millis, int nanos) throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("millis < 0: " + millis);
        }
        if (nanos < 0) {
            throw new IllegalArgumentException("nanos < 0: " + nanos);
        }
        if (nanos > 999999) {
            throw new IllegalArgumentException("nanos > 999999: " + nanos);
        }
    
        // The JLS 3rd edition, section 17.9 says: "...sleep for zero
        // time...need not have observable effects."
        if (millis == 0 && nanos == 0) {
            // ...but we still have to handle being interrupted.
            if (Thread.interrupted()) {
              throw new InterruptedException();
            }
            return;
        }
    
        long start = System.nanoTime();
        long duration = (millis * NANOS_PER_MILLI) + nanos;
    
        Object lock = currentThread().lock;
    
        // Wait may return early, so loop until sleep duration passes.
        synchronized (lock) {
            while (true) {
                sleep(lock, millis, nanos);
    
                long now = System.nanoTime();
                long elapsed = now - start;
    
                if (elapsed >= duration) {
                    break;
                }
    
                duration -= elapsed;
                start = now;
                millis = duration / NANOS_PER_MILLI;
                nanos = (int) (duration % NANOS_PER_MILLI);
            }
        }
    }

03.sleep(0)作用是什么

  • Thread.Sleep(0) 。既然是 Sleep 0 毫秒,那么他跟去掉这句代码相比,有啥区别么?
    • 答案是:有,而且区别很明显。Thread.Sleep(0)的作用,就是“触发操作系统立刻重新进行一次CPU竞争”。竞争的结果也许是当前线程仍然获得CPU控制权,也许会换成别的线程获得CPU控制权。这也是我们在大循环里面经常会写一句Thread.Sleep(0),因为这样就给了其他线程比如Paint线程获得CPU控制权的权力,这样界面就不会假死在那里。
  • sleep(0)会抛出异常吗?
    • 会抛出异常,代码如下所示
    public static void sleep(long millis, int nanos)
        throws InterruptedException {
            if (millis < 0) {
                throw new IllegalArgumentException("millis < 0: " + millis);
            }
            if (nanos < 0) {
                throw new IllegalArgumentException("nanos < 0: " + nanos);
            }
            if (nanos > 999999) {
                throw new IllegalArgumentException("nanos > 999999: " + nanos);
            }
    
            // The JLS 3rd edition, section 17.9 says: "...sleep for zero
            // time...need not have observable effects."
            if (millis == 0 && nanos == 0) {
                // ...but we still have to handle being interrupted.
                if (Thread.interrupted()) {
                  throw new InterruptedException();
                }
                return;
            }

赞赏支持


精彩留言

发表评论