2

一个线程打开一个资源,这是一个阻塞操作。如果成功,则线程需要再次关闭它,这又是阻塞的,但总是在有限的时间内成功。

可以使用一个标志(我们称之为它hasResource),它不能以任何方式与其他线程同步,以表明该线程不想被中断。根本不允许其他同步。

以下是处理这种情况的安全方法吗?

@Override // we're subclassing Thread
public void run () {
    try {
        while (!interrupted ()) {
            blockingOpen ();
            // glitch possibility in this line
            hasResource = true;
            blockingClose ();
            hasResource = false;
        }
    }
    catch (final InterruptedException e) {
        interrupt ();
    }
}

特别是,这是否确保线程在拥有资源时不会被中断?

据我所知,只有一个错误机会窗口,即在打开之后和设置标志之前。但是,这似乎不会导致资源泄漏,而是会意外忽略中断请求。有可能防止这种情况吗?

4

2 回答 2

1

原始代码实际上是正确的。设置 bool 标志不是问题,即使问题错误地暗示它可能是。要明确这一点,需要考虑两点:

首先,线路本身不会导致错误。如果打开成功,标志被设置 - 总是。甚至 StackOverflow 或 OutOfMemory 都不能在这里合理地发生。

其次,如果interrupt()在没有执行可中断代码(例如睡眠)时调用,则将interrupted设置该标志。下一次任何可中断的代码开始执行时,都会检查这个标志,而不是运行代码,而是抛出一个被中断的异常。

因此,原始代码确实按预期工作。

于 2017-08-14T22:59:08.507 回答
0

可以使用一个不能以任何方式与其他线程同步的标志(我们称之为hasResource)来表示该线程不想被中断。根本不允许其他同步。

不,不是。

这是否确保线程在拥有资源时不会被中断?

不,如果 hasResourceisvolatile 所有其他线程都知道hasResource 观察它,那么你已经禁止自己调用Thread.interrupt(),但你没有禁止Java这样做。

为什么您的应用程序线程会相互中断是另一个问题。20 年来从未使用过此功能。

于 2017-08-14T23:26:10.413 回答