java 中断等待阻塞操作的线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1820118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Interrupting a thread that waits on a blocking action?
提问by Yossale
I am running a thread whose main action is to call on a proxy using a blocking function , and wait for it to give it something.
我正在运行一个线程,其主要操作是使用阻塞函数调用代理,并等待它给它一些东西。
I've used the known pattern of a volatile boolean and the Interruption , but I'm not sure it will work: When I tried to add a catch block for InterruptedException, I get the error:
我使用了 volatile 布尔值和 Interruption 的已知模式,但我不确定它是否会起作用:当我尝试为 添加 catch 块时InterruptedException,出现错误:
Unreachable catch block for InterruptedException. This exception is never thrown from the try statement body
无法访问 InterruptedException 的 catch 块。这个异常永远不会从 try 语句体中抛出
So if I'm never going to get anInterruptedException, this means I'll never get out of the blocking action - thus will never stop.
因此,如果我永远不会得到InterruptedException,这意味着我永远不会摆脱阻塞操作 - 因此永远不会停止。
I'm a bit puzzled. Any idea?
我有点不解。任何的想法?
public void run() {
Proxy proxy = ProxyFactory.generateProxy();
Source source;
while (!isStopped) {
try {
source = proxy.getPendingSources();
scheduleSource(source);
} catch (Exception e) {
log.error("UnExpected Exception caught while running",e);
}
}
}
public void stop() {
this.isStopped = true;
Thread.currentThread().interrupt();
}
回答by Kevin
First, you don't really need a separate flag (if you do, use an AtomicBoolean), just check Thread.currentThread().isInterrupted()as your while condition.
首先,您实际上并不需要单独的标志(如果需要,请使用AtomicBoolean),只需检查Thread.currentThread().isInterrupted()您的 while 条件即可。
Second, your stop method won't work because it won't interrupt the correct thread. If another thread calls stop, the code uses Thread.currentThread()which means the calling thread will be interrupted, not the running one.
其次,您的 stop 方法将不起作用,因为它不会中断正确的线程。如果另一个线程调用 stop,代码使用Thread.currentThread()这意味着调用线程将被中断,而不是正在运行的线程。
Finally, what is the blocking method? Is it scheduleSource()? If that method doesn't throw InterruptedException, you won't be able to catch it.
最后,什么是阻塞方法?是scheduleSource()吗?如果该方法没有 throw InterruptedException,您将无法捕捉到它。
Try the following:
请尝试以下操作:
private final AtomicReference<Thread> currentThread = new AtomicReference<Thread>();
public void run() {
Proxy proxy = ProxyFactory.generateProxy();
Source source;
currentThread.set(Thread.currentThread());
while (!Thread.currentThread().isInterrupted()) {
try {
source = proxy.getPendingSources();
scheduleSource(source);
} catch (Exception e) {
log.error("UnExpected Exception caught while running", e);
}
}
}
public void stop() {
currentThread.get().interrupt();
}
回答by erickson
Only a few, well-defined "blocking methods" are interruptible. If a thread is interrupted, a flag is set, but nothing else will happen until the thread reaches one of these well-defined interruption points.
只有少数明确定义的“阻塞方法”是可中断的。如果线程被中断,则会设置一个标志,但在线程到达这些明确定义的中断点之一之前,不会发生任何其他事情。
For example, read()and write()calls are interruptible if they are invoked on streams created with a InterruptibleChannel. If a Socketis used as the starting point, calling interrupt()on a Threadblocked in the read has no effect. Note that if a blocking I/O operation is interrupted successfully, the underlying channel is closed.
例如,read()并且write()如果他们是在与创建的流调用的调用是中断的InterruptibleChannel。如果以 aSocket为起点,则调用interrupt()在Thread读取中阻塞的a无效。请注意,如果成功中断阻塞 I/O 操作,则底层通道将关闭。
Another large class of interruptible operations are those thrown by various blocking operations on classes in the java.util.concurrentpackages. Of course, the original wait()method is interruptible as well.
另一大类可中断操作是由java.util.concurrent包中的类的各种阻塞操作引发的操作。当然,原始wait()方法也是可中断的。
Blocking methods can be identified by looking for a throws InterruptedExceptionin their method signatures. They should be well-documented too, to describe any side-effects of interruption.
可以通过throws InterruptedException在方法签名中查找 a 来识别阻塞方法。它们也应该有详细记录,以描述中断的任何副作用。
You can write an interruptible method of your own, but it has to be composed of interruptible lower-level operations itself.
您可以编写自己的可中断方法,但它必须由可中断的低级操作本身组成。
回答by Ben S
You stopmethod is calling interrupton the wrong thread. Thread.currentThread()is the thread that is interrupting, not being interrupted.
您的stop方法调用interrupt了错误的线程。Thread.currentThread()是正在中断的线程,而不是被中断的线程。
回答by irreputable
ok, people, don't kill me over this.
好吧,伙计们,不要因为这个而杀了我。
I experimented with Thread.stop() for fun, to kick thread out of a blocking action, catch ThreadDeath, keep target thread alive, and move on.
为了好玩,我尝试了 Thread.stop(),将线程踢出阻塞操作,捕获 ThreadDeath,保持目标线程处于活动状态,然后继续前进。
It seems working. The world isn't ending. But I'm just saying. You are responsible for you own doing. Why am I rapping?
它似乎工作。世界并没有结束。但我只是说。你对你自己的所作所为负责。我为什么要说唱?
回答by Gazzonyx
How are you calling stop from the executing thread?
If you call stop() from another thread, you'll kill it, not the thread running in the try/catch block.
你如何从正在执行的线程中调用 stop ?
如果您从另一个线程调用 stop(),您将杀死它,而不是在 try/catch 块中运行的线程。

