公司项目改BUG:子线程异常信息无法传递到主线程

博客讲述了在多线程环境下,如何处理子线程异常并将其传递给主线程。当子线程抛出异常时,JVM默认处理不会传递给主线程。解决方案包括使用Callable接口的call方法捕获异常,设置未捕获异常处理器,通过共享变量或队列进行线程间通信,确保主线程能够获取并处理子线程的异常信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

问题出现

简单逻辑描述:
用户下载模板上传的excel文件,然后填写后导入服务器,其中有一些字段有填写要求(例如A中填写1,则B只能填写1)。用户将excel文件导入服务器的时候,服务器基于多线程进行校验,如果校验失败则会抛出业务异常。然后将异常信息发给前台,进行提示。

现在问题是,线程抛出异常后没有被主线程拿到,而是直接被JVM处理了(在服务器终端打印堆栈信息)

我要做的就是,让主线程拿到子线程的异常信息,然后返回给前台

问题解决

以上这个问题如果复习过线程、线程池相关的资料,一眼就能能看出来,这是一个“子线程异常传递”的问题。
幸好之前总结过这类问题,没想到居然在公司改BUG的时候用到了

【1】给线程布置任务有两个接口,一个是runnable(对应run方法),另一个是callable(对应call方法),前者声明的时候没有抛出异常(throws Exception),而后者声明了异常。
通过这次改BUG最直观的感受就是:
run方法中,如果遇到编译期异常(例如IOException)一定要在run方法内部完成处理,不能够向上抛出。

                                if(isMatch){
   
                                    throw new IOException("导入数据不符合规范");
                                }

而要该的代码中,抛出的就是一个受检异常。

虽然run方法的checked exception必须处理,但是runtime exception是可以抛出的,那么我是不是可以把IO exception的message取出来,重新包装为一个runtimeException。

        catch (InvocationTargetException e
### 回答1: 这段代码有两个问题: 1. 缺少必要的导入模块,需要先导入keyboard模块: ```python import keyboard import os ``` 2. `keyboard.wait()`会阻塞程序执行,需要在按下快捷键后立即退出程序,可以使用`keyboard.wait('esc')`代替。 修复后的代码如下: ```python import keyboard import os keyboard.add_hotkey('space', os.system, args=('shutdown /s /t 0',)) keyboard.wait('esc') ``` 这段代码会在按下空格键后关机,并在按下ESC键后退出程序。 ### 回答2: 这段代码可能存在一个bug。问题在于,在使用键盘库时,代码通常需要在主线程中运行,而主线程通常会被阻塞,直到键盘事件触发才会继续执行。然而,将代码放在主线程中运行的同时,又将关闭计算机命令作为单独的子进程来执行,这可能导致阻塞主线程的问题。 为了解决这个问题,可以尝试使用多线程来分离键盘监听和关闭计算机的操作。代码如下: ```python import keyboard import os import threading def shutdown(): os.system('shutdown /s /t 0') def main(): keyboard.add_hotkey('space', shutdown) keyboard.wait() if __name__ == '__main__': threading.Thread(target=main).start() ``` 在修复的代码中,我们创建了一个名为`shutdown`的函数,该函数执行关闭计算机的操作。然后,我们通过多线程的方式将键盘监听逻辑和关闭计算机逻辑分离。 这样,主线程仅负责监听键盘事件,而子线程负责执行关闭计算机命令。这样就避免了阻塞主线程的问题,使整个程序能够正常运行。 ### 回答3: 这段代码有潜在的bug。该代码使用`keyboard`库来注册热键,并在按下空格键时执行`os.system`函数来运行命令`shutdown /s /t 0`关机电脑。然后使用`keyboard.wait()`函数等待程序运行,但是存在一个问题。 该问题是`keyboard.wait()`会导致程序运行时的阻塞,即程序会停下来等待按键触发。而在此期间,主线程不会执行`os.system`函数来关机电脑。修复这个问题的方法是使用多线程。 下面是修复后的代码: ```python import keyboard import os import threading def shutdown(): os.system('shutdown /s /t 0') thread = threading.Thread(target=shutdown) thread.daemon = True keyboard.add_hotkey('space', thread.start) keyboard.wait() ``` 修复后的代码使用了多线程来解决阻塞问题。将关机操作放在一个名为`shutdown`的函数中,并使用`threading.Thread`创建一个线程来执行该函数。将`thread.daemon`设置为True,可以使程序在主线程结束时退出,同时也确保了程序可以正常关闭。 然后注册热键时,直接传递`thread.start`函数来启动新线程,而不会阻塞主线程。这样,按下空格键时,`os.system`函数会在新线程中执行,实现关机操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值