java - CountDownLatch 中断异常

标签 java multithreading exception-handling

我正在使用 CountDownLatch在两个线程之间同步初始化过程,我想知道如何正确处理 InterruptedException它可能会抛出。

我最初写的代码是这样的:

    private CountDownLatch initWaitHandle = new CountDownLatch(1);
    /**
     * This method will block until the thread has fully initialized, this should only be called from different threads  Ensure that the thread has started before this is called.
     */
    public void ensureInitialized()
    {
        assert this.isAlive() : "The thread should be started before calling this method.";
        assert Thread.currentThread() != this, "This should be called from a different thread (potential deadlock)";
        while(true)
        {
            try
            {
                //we wait until the updater thread initializes the cache
                //that way we know 
                initWaitHandle.await();
                break;//if we get here the latch is zero and we are done
            } 
            catch (InterruptedException e)
            {
                LOG.warn("Thread interrupted", e);
            }
        }
    }

这个模式有意义吗?基本上忽略 InterruptedException 是个好主意一直等到它成功。我想我只是不明白在什么情况下这会被打断,所以我不知道我是否应该以不同的方式处理它们。

为什么会在此处抛出 InterruptedException,处理它的最佳做法是什么?

最佳答案

这正是您不应该为 InterruptedException 做的事情。 InterruptedException 基本上是对该线程终止的礼貌请求。线程应尽快清理并退出。

IBM 发表了一篇关于此的好文章:http://www.ibm.com/developerworks/java/library/j-jtp05236.html

这是我会做的:

// Run while not interrupted.
while(!(Thread.interrupted())
{
    try
    {
        // Do whatever here.
    }
    catch(InterruptedException e)
    {
        // This will cause the current thread's interrupt flag to be set.
        Thread.currentThread().interrupt();
    }
}

// Perform cleanup and exit thread.

这样做的好处是:如果您的线程在阻塞方法中被中断,则不会设置中断位,而是抛出 InterruptedException。如果您的线程在未处于阻塞方法时被中断,中断位将被设置,并且不会抛出异常。因此,通过调用 interrupt() 设置异常标志,两种情况都被规范化为第一种情况,然后由循环条件检查。

作为额外的好处,这还可以让您通过简单地中断线程来停止线程,而不是发明自己的机制或接口(interface)来设置一些 boolean 标志来做完全相同的事情。

关于java - CountDownLatch 中断异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3168430/

相关文章:

java - 如何在不使用 static 的情况下更改另一个类的变量?

java - 处理草图无法用java在线运行?

Python:防止信号传播到子线程

java - 一个线程是否保证 servlet 处理的整个请求?

java - JOptionPane : change the Icon

java - Hazelcast Hibernate CacheKey 大小

c++ - 使用线程矩阵求逆较慢

Java - TCP - 多线程服务器 - 如何处理多个客户端连接?

php - 在 PHP 中使用异常的正确方法是什么?

wcf - ELMAH 的错误日志记录在带有 basicHttpBinding 的 IIS 中托管的 WCF 服务中不起作用