Java:在Runnable中处理RuntimeException

去年年底,我正在运行预定的任务来监视Neo4j集群,而我遇到的问题之一是有时监视会退出。

我最终意识到这是因为RuntimeException被抛出到Runnable方法中,而我没有处理它。 以下代码演示了该问题:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;public class RunnableBlog {public static void main(String[] args) throws ExecutionException, InterruptedException {ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();executor.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " -> " + System.currentTimeMillis());throw new RuntimeException("game over");}}, 0, 1000, TimeUnit.MILLISECONDS).get();System.out.println("exit");executor.shutdown();}
}

如果运行该代码,我们将看到RuntimeException,但是执行器不会退出,因为线程在没有通知的情况下就死了:

Exception in thread "main" pool-1-thread-1 -> 1391212558074
java.util.concurrent.ExecutionException: java.lang.RuntimeException: game overat java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)at java.util.concurrent.FutureTask.get(FutureTask.java:111)at RunnableBlog.main(RunnableBlog.java:11)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:601)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.RuntimeException: game overat RunnableBlog$1.run(RunnableBlog.java:16)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)at java.lang.Thread.run(Thread.java:722)

当时我最终添加了一个try catch块并打印如下异常:

public class RunnableBlog {public static void main(String[] args) throws ExecutionException, InterruptedException {ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();executor.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName() + " -> " + System.currentTimeMillis());throw new RuntimeException("game over");} catch (RuntimeException e) {e.printStackTrace();}}}, 0, 1000, TimeUnit.MILLISECONDS).get();System.out.println("exit");executor.shutdown();}
}

据我所知,这允许异常被识别,并且执行Runnable的线程不会死亡。

java.lang.RuntimeException: game over
pool-1-thread-1 -> 1391212651955at RunnableBlog$1.run(RunnableBlog.java:16)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)at java.lang.Thread.run(Thread.java:722)
pool-1-thread-1 -> 1391212652956
java.lang.RuntimeException: game overat RunnableBlog$1.run(RunnableBlog.java:16)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)at java.lang.Thread.run(Thread.java:722)
pool-1-thread-1 -> 1391212653955
java.lang.RuntimeException: game overat RunnableBlog$1.run(RunnableBlog.java:16)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)at java.lang.Thread.run(Thread.java:722)

这很好,使我能够继续监视集群。

但是,我最近开始阅读“ Java Concurrency in Practice ”(购买后仅6年!),并意识到这可能不是处理RuntimeException的正确方法。

public class RunnableBlog {public static void main(String[] args) throws ExecutionException, InterruptedException {ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();executor.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName() + " -> " + System.currentTimeMillis());throw new RuntimeException("game over");} catch (RuntimeException e) {Thread t = Thread.currentThread();t.getUncaughtExceptionHandler().uncaughtException(t, e);}}}, 0, 1000, TimeUnit.MILLISECONDS).get();System.out.println("exit");executor.shutdown();}
}

我认为这两种方法之间没有太大区别,所以如果有人可以向我解释为什么这种方法比我以前的捕获异常并打印堆栈跟踪的方法更好的话,那将是一个很好的选择。

参考: Java:通过Mark Needham博客博客的JCG合作伙伴 Mark Needham 处理可运行的RuntimeException 。

翻译自: https://www.javacodegeeks.com/2014/02/java-handling-a-runtimeexception-in-a-runnable.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

错误代码: 1231 - Variable 'sql_mode' can't be set to the value of 'NULL'

错误代码: 1231 - Variable sql_mode cant be set to the value of NULL 错误代码: 1231 - Variable sql_mode cant be set to the value of NULL 错误代码: 1231 - Variable sql_mode cant be set to the value of NULL mysql中的提示 删除注…

[Unity3D]Unity3D游戏开发之怪物AI

大家好。欢迎大家关注由我为大家带来的Unity3D游戏开发系列文章,我的博客地址为:http://blog.csdn.net/qinyuanpei。在上一篇文章中,我们基本上实现了一个小地图的功能,今天呢,我们来实现怪物AI,所谓怪物AI…

中国第一批写java的人_中国java开源界最可爱的人们

评论# re: 中国java开源界最可爱的人们2007-12-07 15:29sitinspring如果少一些抒情,多一点实质内容,文章更耐看. 回复 更多评论# re: 中国java开源界最可爱的人们[未登录]2007-12-07 15:49dennis竟然没有满江红,opendoc的意义不用多说了吧 回复 更多评论# re: 中…

如何把握好 transition 和 animation 的时序,创作描边按钮特效

效果预览 在线演示 按下右侧的“点击预览”按钮可以在当前页面预览,点击链接可以全屏预览。https://codepen.io/comehope/pen/mKdzZM可交互视频教程此视频是可以交互的,你可以随时暂停视频,编辑视频中的代码。请用 chrome, safari, edge 打…

使用PHREAK算法实现Drools 6性能

Drools 6引入了新的惰性匹配算法。 该算法的详细信息已在之前的两个博客中介绍: RIP RETE时间获得PHREAKY 基于PHREAK堆栈的评估和向后链接 第一篇文章讨论了性能以及为什么算法的批处理和惰性方面难以比较。 “性能的最后一点。 通常,使用PHREAK的单…

02Data

1.数据从何而来 2.数据对象和属性类型 数据集合的类型 结构数据的重要特征 数据对象 属性 属性类型 数据属性的类型 离散 vs.连续属性 3.数据的(基本)统计描述 分布度量 代数度量 整体度量 度量数据的中心趋势 对称/偏斜数据 4.数据可视化 5.数据的相似…

PAT 1131 Subway Map

题目链接&#xff1a; https://pintia.cn/problem-sets/994805342720868352/problems/994805347523346432 思路&#xff1a; 说多了都是泪&#xff0c; Dijstra超时&#xff0c;采用dfs 利用map<pair<int,int>,int>&#xff0c;表示两个点和他们中间的地铁线号 每次…

专访Vue作者尤雨溪:Vue CLI 3.0重构的原因

1、为什么要对 Vue CLI 进行大规模修改&#xff1f; 尤雨溪认为旧版本的 Vue CLI 本质上只是从 GitHub 拉取模版&#xff0c;这种拉模版的方式有几个问题&#xff1a; &#xff08;1&#xff09; 在单个模版里面同时支持太多选项会导致模版本身变得极其复杂和难以维护&#x…

java秒杀时间与服务器时间_Javascript实现秒杀倒计时(时间与服务器时间同步)...

现在有很多网站都在做秒杀商品&#xff0c;而这其中有一个很重要的环节就是倒计时。关于倒计时&#xff0c;有下面几点需要注意&#xff1a;1.应该使用服务器时间而不是本地时间(本地时间存在时区不同、用户自行设置等问题)。2.要考虑网络传输的耗时。3.获取时间时可直接从AJAX…

Java 8 Friday Goodies:本地交易范围

在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 &#xff0c;现在我们觉得是时候开始一个新的博客系列了…

Python3.5-20190501-廖老师的

python是一门解释型\脚本语言(和js特别像,如果同时学习js和python完全搅浑了.) 在运行py时候是一句一句翻译成cpu识别的机器码,所以速度比较慢.而C程序是运行前直接编译成CPU能执行的机器码&#xff0c;所以非常快. 学习python,就需要安装python.安装的同时会有一个解释器,就是…

如何用纯 CSS 创作一个冒着热气的咖啡杯

效果预览 在线演示 按下右侧的“点击预览”按钮在当前页面预览&#xff0c;点击链接全屏预览。https://codepen.io/zhang-ou/pen/xjXxoz可交互视频教程此视频是可以交互的&#xff0c;你可以随时暂停视频&#xff0c;编辑视频中的代码。请用 chrome, safari, edge 打开观看。…

用keras实现基本的回归问题

数据集介绍 共有506个样本&#xff0c;拆分为404个训练样本和102个测试样本 该数据集包含 13 个不同的特征&#xff1a; 人均犯罪率。占地面积超过 25000 平方英尺的住宅用地所占的比例。非零售商业用地所占的比例&#xff08;英亩/城镇&#xff09;。查尔斯河虚拟变量&#xf…

Java:计算类的serialVersionUID

在本周早些时候&#xff0c;我想计算可序列化类的serialVersionUID &#xff0c;以便可以覆盖其toString方法而不会破坏所有内容。 我遇到了Frank Kim的博客文章 &#xff0c;该文章建议使用JDK附带的serialver工具。 我创建了一个Maven小项目来在一个非常简单的类上测试该工…

Codeforces Round #556 (Div. 1)

Codeforces Round #556 (Div. 1) A. Prefix Sum Primes 给你一堆1,2&#xff0c;你可以任意排序&#xff0c;要求你输出的数列的前缀和中质数个数最大。 发现只有\(2\)是偶质数&#xff0c;那么我们先放一个\(2\)&#xff0c;再放一个\(1\)&#xff0c;接下来把\(2\)全部放掉再…

FC冒险岛java版_冒险岛单机版

游戏概述冒险岛单机版是一款非常好玩的横版动作RPG游戏&#xff0c;游戏难度很适中&#xff0c;冒险岛单机版采用了与其他Q版2D游戏不同的横向卷轴的移动方式&#xff0c;场景高低落差的设计&#xff0c;整个画面层次感设计算是一级&#xff0c;喜欢这类手柄闯关游戏的玩家快来…

通过小程序实现网站扫码登录!每年都可以省 300 块...代替微信开放平台和服务号的登陆模式!

我们知道&#xff0c;要接入微信登陆有两种方式 1、微信开放平台2、微信服务号 这两种方式均可生成带参数的二维码&#xff0c;然后扫码获取用户基本信息的&#xff0c;所以我们可以在网站上用这两种方式开发网站的扫码登录&#xff0c;也是现在很多网站的通用做法。 微信开…

WAR文件与具有嵌入式服务器的Java应用程序

大多数服务器端Java应用程序&#xff08;例如&#xff0c;面向Web或面向服务的&#xff09;都希望在容器中运行。 打包这些应用程序以进行分发的传统方法是将它们捆绑为WAR文件。 这无非是具有标准目录布局的ZIP归档文件&#xff0c;其中包含运行时所需的所有库和应用程序级依赖…

JavaFX自定义控件– Nest Thermostat第3部分

嗨&#xff0c;经过与同事的讨论&#xff0c;我今天决定展示css方法不是唯一可用于创建自定义控件的方法。 当然&#xff0c;它允许提供一些外观扩展点&#xff0c;但是可以使用代码API使用相同的方法&#xff08;与向JavaFX的转换&#xff09;一起使用。 这是图形初始化方法&…

ceph rgw java_ceph rgw multisite基本用法

Realm&#xff1a; Zonegroup&#xff1a; 理解为数据中心&#xff0c;由一个或多个Zone组成&#xff0c;每个Realm有且仅有 一个Master Zonegroup&#xff0c;用于处理系统变更&#xff0c;其他的称为Slave Zonegroup&#xff0c;元数据与Master Zonegroup保持一致&#xff1b…