JAVA技术分享:消失的线程
很多小伙伴都问过我一个问题,就是任务线程跑着跑着消失了,而且没有任何异常日志。我都是条件反射式的回复,是不是用了线程池的submit提交任务。而且很大几率对方给予肯定答复。
解决方案,很多人都听过不少,下面我就分析一下原因以及最佳实践。
为什么消失
submit这个单词用的真的特别好,特别洋气,虽然可以用execute来提交,但是大部分人都是用的submit。问题也就出在submit上了。
public Future? submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture ftask = newTaskFor(task, null); execute(ftask); return ftask; }
submit也是调用的execute,而且是有Future的返回值的。他把一个Runnable 组装成了一个无返回类型的FutureTask。
FutureTask的run方法与众不同。
public void run() { .... try { Callable c = callable; if (c != null state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { .... } }
可以看到FutureTask的run自己捕获了Throwable 而且没有抛出,线程里的所有代码出了什么错都会被捕获,并且赋值给了成员变量outcome。
最终在get里调用report有一段逻辑可以取出异常
private V report(int s) throws ExecutionException { Object x = outcome; if (s == NORMAL) return (V)x; if (s = CANCELLED) throw new CancellationException(); throw new ExecutionException((Throwable)x); }
最后异常会在get的时候throw。
程序出错,异常被吞掉了,最终展现出业务线程消失的现象。
解决方案
run里自己编码解决异常
自己的代码健壮到一言不合来个大写的try catch 而且一定是Throwable并且要合理的记录 。写这种代码真心累,而且在一些特殊场合才这么干,例如javaagent。搞个探针上去,一堆异常在业务系统上,换谁谁都怕。
future.get()
submit的时候会返回一个Future,我们只要get就可以获取到异常。这个是一个理论可行的方案,这个也只用在有交互的场景,例如出现异常了再次提交任务等等。再交互的场景下,这个方案特别适合。
execute提交
submit最终也调用的execute。execute只能接收参数Runnable。
execute直接把异常给抛出了,就是不怎么优雅的记录。
try { beforeExecute(wt, task); Throwable thrown = null; try { task.run(); } catch (RuntimeException x) { thrown = x; throw x; } catch (Error x) { thrown = x; throw x; } catch (Throwable x) { thrown = x; throw new Error(x); } finally { afterExecute(task, thrown); }
每个work执行的时候虽然也会捕获各种异常,但是最后都throw出来了,也能达到追踪的效果。
自定义线程池
继承线程池然后复写afterExecute(task, thrown);上面也看到了最后会执行这个方法,而且可以优雅的记录日志,以及可以做一些补偿操作再里面。
最佳实践
一般使用线程池都会自己去自定义,毕竟为了区别,我们会自己去写线程工厂去标识自己的线程,而且为了内存估计会调整阻塞队列的类型和大小,在一些压力突增的情况还得控制线程池里最大线程的个数与核心线程的比率,所以线程池的自定义是很有必要的。推荐使用自定义线程池的方式记录日志。并不推荐补偿等逻辑也写在线程池里,对于要补偿的情况推荐future.get()。这里只写异常的处理和补偿即可,日志就不用记录了。
JAVA技术分享:消失的线程的更多相关文章
- JAVA技术专题综述之线程篇(1)
本文详细介绍JAVA技术专题综述之线程篇 编写具有多线程能力的程序经常会用到的方法有: run(),start(),wait(),notify(),notifyAll(),sleep(),yield( ...
- Java技术分享:如何编写servlet程序
身为计算机专业的我,从接触java至今,已经有七年之久,从最开始的小白到现在的大白,这是一个漫长而曲折的历程. 大学刚接触Java这个学科时,一点儿都不理解java是要干嘛的,只知道学起来肯定不容易, ...
- java 技术分享
http://www.ccblog.cn/99.htm http://www.ccblog.cn/100.htm http://www.ccblog.cn/101.htm http://www.ccb ...
- 最值得收藏的java技术博客(Java篇)
第一个:java_my_life 作者介绍:找不到原作者信息.大概做了翻阅全部是2012年的博客. 博客主要内容:主要内容是关于Java设计模式的一些讲解和学习笔记,在相信对学习设计模式的同学帮助很大 ...
- 爱奇艺技术分享:爱奇艺Android客户端启动速度优化实践总结
本文由爱奇艺技术团队原创分享,原题<爱奇艺Android客户端启动优化与分析>. 1.引言 互联网领域里有个八秒定律,如果网页打开时间超过8秒,便会有超过70%的用户放弃等待,对Andro ...
- 微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)
1.点评 对于IM系统来说,如何做到IM聊天消息离线差异拉取(差异拉取是为了节省流量).消息多端同步.消息顺序保证等,是典型的IM技术难点. 就像即时通讯网整理的以下IM开发干货系列一样: <I ...
- 推荐:7 月份值得一看的 Java 技术干货!
月底了,又到了我们总结这一个月 Java 技术干货的时候了,又到了我们给粉丝免费送书的日子了. 7 月份干货总结 Oracle 发布了一个全栈虚拟机 GraalVM 一文带你深入拆解 Java 虚拟机 ...
- UWA 技术分享连载 转载
技术分享连载1 Q1:Texture占用内存总是双倍,这个是我们自己的问题,还是Unity引擎的机制? Q2:我现在发现两个因素直接影响Overhead,一个是Shader的复杂度,一个是空Updat ...
- 技术分享之AQS——内容提要
1. 背景 最近团队内部技术分享,我做了个关于AQS的分享.ppt中涵盖的部分要点内容,现在整理到博客上. 关于AQS本身的源码解读,可以参考我之前的博文. 2. 要点梳理 下面是一些技术分享的要点梳 ...
随机推荐
- [转]CentOS 6.4下Squid代理服务器的安装与配置
一.简介 代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息. Squid是一个缓存Internet 数据的软件,其接收用户的下载申请,并自动处理所下载的数据.当一个用 ...
- Oracle数据库误删文件导致rman备份报错RMAN-06169解决办法
Oracle数据库误删文件导致rman备份报错RMAN-06169解决办法 可能是误删文件导致在使用rman备份时候出现以下提示 RMAN-06169: could not read file hea ...
- poj1952 BUY LOW, BUY LOWER【线性DP】【输出方案数】
BUY LOW, BUY LOWER Time Limit: 1000MS Memory Limit: 30000K Total Submissions:11148 Accepted: 392 ...
- java 中的控制台端口的输入
java 中基于控制台端的输入时最基本的操作. 第一步 导入Scanner类 import java.util.Scanner; 第二步 创建输入对象 input Scanner input=new ...
- oracle goldengate安装
1.ftp工具上传ogg112101_fbo_ggs_Linux_x64_ora11g_64bit.zip分别到source和target服务器 [oracle@localhost mnt]$ ll ...
- MySQL 数据库的主从配置
mysql主从配置.鄙人是在如下环境测试的: 主数据库所在的操作系统:win7 主数据库的版本:5.0 主数据库的ip地址:192.168.1.111 从数据库所在的操作系统:linux 从数据的版本 ...
- Python开发【前端】:Ajax(二)
原生Ajax.JQuery.伪Ajax三种方式使用优先级 如果发送的是[普通数据] jQuery XMLHttpRequest iframe 如果发送的是[文件] iframe jQuery(Form ...
- render的几个应用
1.render可以通过模版语法来渲染字符串,例如变量,标签,for循环,这里就不赘述,我就举个自己印象很深刻灵活应用,看看render到底做了什么,关心什么 注意! 在rander眼里,没有html ...
- mysql 数据操作 单表查询 limit 练习
1. 分页显示,每页5条 mysql,; +----+------------+--------+-----+------------+---------+--------------+------- ...
- 002-and design-基于dva的基本项目搭建
一.概述 在真实项目开发中,你可能会需要 Redux 或者 MobX 这样的数据应用框架,Ant Design React 作为一个 UI 库,可以和任何 React 生态圈内的应用框架搭配使用.我们 ...