中断等待阻塞操作的线程?

时间:2023-02-03 21:02:56

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:

我已经使用了挥发性布尔值和中断的已知模式,但我不确定它是否会起作用:当我尝试为InterruptedException添加一个catch块时,我收到错误:

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.

因此,如果我永远不会得到anInterruptedException,这意味着我永远不会摆脱阻塞行为 - 因此永远不会停止。

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();
  }

5 个解决方案

#1


11  

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()吗?如果该方法不抛出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();
}

#2


10  

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 Socket is used as the starting point, calling interrupt() on a Thread blocked in the read has no effect. Note that if a blocking I/O operation is interrupted successfully, the underlying channel is closed.

例如,如果在使用InterruptibleChannel创建的流上调用read()和write()调用,则它们是可中断的。如果使用Socket作为起始点,则在读取中阻塞的线程上调用interrupt()无效。请注意,如果阻塞I / O操作成功中断,则关闭基础通道。

Another large class of interruptible operations are those thrown by various blocking operations on classes in the java.util.concurrent packages. Of course, the original wait() method is interruptible as well.

另一大类可中断操作是由java.util.concurrent包中的类对各种阻塞操作抛出的操作。当然,原始的wait()方法也是可以中断的。

Blocking methods can be identified by looking for a throws InterruptedException in their method signatures. They should be well-documented too, to describe any side-effects of interruption.

可以通过在方法签名中查找抛出InterruptedException来识别阻塞方法。它们也应该被充分记录,以描述中断的任何副作用。

You can write an interruptible method of your own, but it has to be composed of interruptible lower-level operations itself.

您可以编写自己的可中断方法,但它必须由可中断的低级操作本身组成。

#3


2  

You stop method is calling interrupt on the wrong thread. Thread.currentThread() is the thread that is interrupting, not being interrupted.

你停止方法是在错误的线程上调用中断。 Thread.currentThread()是正在中断但不被中断的线程。

#4


2  

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?

看起来很有效。世界没有结束。但我只是说。你对自己的行为负责。我为什么要说唱?

#5


1  

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块中运行的线程。

#1


11  

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()吗?如果该方法不抛出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();
}

#2


10  

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 Socket is used as the starting point, calling interrupt() on a Thread blocked in the read has no effect. Note that if a blocking I/O operation is interrupted successfully, the underlying channel is closed.

例如,如果在使用InterruptibleChannel创建的流上调用read()和write()调用,则它们是可中断的。如果使用Socket作为起始点,则在读取中阻塞的线程上调用interrupt()无效。请注意,如果阻塞I / O操作成功中断,则关闭基础通道。

Another large class of interruptible operations are those thrown by various blocking operations on classes in the java.util.concurrent packages. Of course, the original wait() method is interruptible as well.

另一大类可中断操作是由java.util.concurrent包中的类对各种阻塞操作抛出的操作。当然,原始的wait()方法也是可以中断的。

Blocking methods can be identified by looking for a throws InterruptedException in their method signatures. They should be well-documented too, to describe any side-effects of interruption.

可以通过在方法签名中查找抛出InterruptedException来识别阻塞方法。它们也应该被充分记录,以描述中断的任何副作用。

You can write an interruptible method of your own, but it has to be composed of interruptible lower-level operations itself.

您可以编写自己的可中断方法,但它必须由可中断的低级操作本身组成。

#3


2  

You stop method is calling interrupt on the wrong thread. Thread.currentThread() is the thread that is interrupting, not being interrupted.

你停止方法是在错误的线程上调用中断。 Thread.currentThread()是正在中断但不被中断的线程。

#4


2  

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?

看起来很有效。世界没有结束。但我只是说。你对自己的行为负责。我为什么要说唱?

#5


1  

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块中运行的线程。