如何从java线程中抛出已检查的异常?

2022-09-01 01:12:18

嘿,我正在编写一个网络应用程序,在其中我读取一些自定义二进制格式的数据包。我正在启动一个后台线程来等待传入的数据。问题是,编译器不允许我将任何代码抛出(选中)异常放入 。它说:run()

run() in (...).Listener cannot implement run() in java.lang.Runnable; overridden method does not throw java.io.IOException

我希望异常杀死线程,并让它被捕获在父线程中的某个位置。这是否可能实现,或者我是否必须处理线程的每个异常?


答案 1

为了能够将异常发送到父线程,您可以将后台线程放在可调用中(它允许抛出也选中的异常),然后将其传递给某个执行程序提交方法。submit 方法将返回一个 Future,然后您可以使用它来获取异常(它的 get 方法将引发一个包含原始异常的执行异常)。


答案 2

注意:如果您必须使用异常机制,这可能不符合您的需求。

如果我对你的理解是正确的,你实际上并不需要检查异常(你已经接受了建议未经检查的异常的答案),那么简单的侦听器模式会更合适吗?

侦听器可以位于父线程中,当您在子线程中捕获已检查的异常时,只需通知侦听器即可。

这意味着您有一种方法可以(通过公共方法)公开这种情况会发生,并且能够传递比异常允许的更多的信息。但这确实意味着父线程和子线程之间将存在耦合(尽管是松散的耦合)。这取决于在您的特定情况下,这是否比用未选中的异常包装已检查的异常有好处。

下面是一个简单的示例(从另一个答案中借用了一些代码):

public class ThingRunnable implements Runnable {
    private SomeListenerType listener;
    // assign listener somewhere

    public void run() {
        try {
            while(iHaveMorePackets()) { 
                doStuffWithPacket();
            }
        } catch(Exception e) {
            listener.notifyThatDarnedExceptionHappened(...);
        }
    }
 }

耦合来自父线程中的对象,该对象的类型必须为 。SomeListenerType