关于程序员:深入理解线程中断方式

47次阅读

共计 1783 个字符,预计需要花费 5 分钟才能阅读完成。

深刻了解线程中断形式

为什么废除 Thread 的 stop 函数?

1.stop 是通过立刻抛出 ThreadDeath 异样,来达到进行线程的目标,此异样抛出有可能产生在任何一时间点,包含在 catch、finally 等语句块中,然而此异样并不会引起程序退出 (笔者只测试了 Java8)。

2. 因为有异样抛出,导致线程会开释全副所持有的锁,极可能引起线程平安问题。

因为以上 2 点,stop 这种形式进行线程是不平安的。

上面是 stop 的源码 (Java8):

    @Deprecated
    public final void stop() {SecurityManager security = System.getSecurityManager();
        if (security != null) {checkAccess();
            if (this != Thread.currentThread()) {security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        // A zero status value corresponds to "NEW", it can't change to
        // not-NEW because we hold the lock.
        if (threadStatus != 0) {resume(); // Wake up thread if it was suspended; no-op otherwise
        }

        // The VM can handle all thread states
        stop0(new ThreadDeath());
    }
    
    private native void stop0(Object o);

上述源码中要害代码就是 stop0(new ThreadDeath()) 函数,这是 Native 函数,传递的参数是 ThreadDeath,ThreadDeath 是一个异样对象,该对象从 Native 层抛到了 Java 层,从而导致线程进行,不过此异样并不会引起程序退出。

很多时候为了保障数据安全,线程中会编写同步代码,如果当线程正在执行同步代码时,此时调用 stop,引起抛出异样,导致线程持有的锁会全副开释,此时就不能确保数据的安全性,呈现无奈预期的错乱数据,还有可能导致存在须要被开释的资源得不到开释,引发内存泄露。所以用 stop 进行线程是不举荐的。

用 Thread 的 interrupt 完结线程

其实调用 Thread 对象的 interrupt 函数并不是立刻中断线程,只是将线程中断状态标记设置为 true,当线程运行中有调用其阻塞的函数(Thread.sleep,Object.wait,Thread.join 等)时,阻塞函数调用之后,会一直地轮询检测中断状态标记是否为 true,如果为 true,则进行阻塞并抛出 InterruptedException 异样,同时还会重置中断状态标记;如果为 false,则持续阻塞,直到阻塞失常完结。

对于 Thread 的动态函数 interrupted 与 Thread 的对象函数 isInterrupted

这两个函数的源码:

    public static boolean interrupted() {return currentThread().isInterrupted(true);
    }
    public boolean isInterrupted() {return isInterrupted(false);
    }
    /**
     * Tests if some Thread has been interrupted.  The interrupted state
     * is reset or not based on the value of ClearInterrupted that is
     * passed.
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

从源码中能够看出,2 函数都是调用了 Native 函数 private native boolean isInterrupted(boolean ClearInterrupted);,前者调用传的参数为 true,所以,调用 interrupted 函数,会在检测线程中断状态标记是否为 true 后,还会将中断状态标记重置为 false。而 isInterrupted 函数只是检测线程中断状态标记

Java 线程中断的正确姿态

线程中如何解决 InterruptedException

正文完
 0