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. 要点梳理 下面是一些技术分享的要点梳 ...
随机推荐
- POM(project Object Model) Maven包管理依赖 pom.xml文件
什么是POM POM全称为“Project Object Model”,意思是工程对象模型.Maven工程使用pom.xml来指定工程配置信息,和其他文本信息.该配置文件以xml为格式,使用xml语法 ...
- 使用 Capistrano 进行自动化部署
最近在折腾这个,弄了好多次都不成功,看了官方文档和很多博客,都没有说清楚,因此,我觉得有必要把它记录下来,以帮助更多像我这样被弄得烦躁的人. 首先是安装,其实 Ubuntu 上面安装 Capistra ...
- 170706、springboot编程之文件上传
使用thymleaf模板,自行导入依赖! 一.单文件上传 1.编写单文件上传页面singleFile.html <!DOCTYPE html> <html xmlns="h ...
- CH5E02 花店橱窗【线性DP】
5E02 花店橱窗 0x5E「动态规划」练习 背景 xq和他的老婆xz最近开了一家花店,他们准备把店里最好看的花都摆在橱窗里.但是他们有很多花瓶,每个花瓶都具有各自的特点,因此,当各个花瓶中放入不同的 ...
- 【优先队列】POJ2010- Moo University-Financial Aid
[题目大意] 给出C头奶牛的SAT成绩和申请奖学金,选出N头牛,使得总奖学金在≤F的情况下奶牛SAT成绩的中位数最大. [思路] 假设before[i]表示前i头奶牛中n/2头奶牛奖学金总额的最小值, ...
- 106 miles to Chicago---zoj2797(最短路问题,求概率,模板)
题目链接:http://www.icpc.moe/onlinejudge/showProblem.do?problemId=1797 题意是有 n 个点 m 条边,从a到b的不被抓的概率是p,让求从点 ...
- 流畅的python 读书笔记 第二章 序列构成的数组 列表推导
列表推导是构建列表(list)的快捷方式,而生成器表达式则可以用来创建其他任何类型的序列.如果你的代码里并不经常使用它们,那么很可能你错过了许多写出可读性更好且更高效的代码的机会. 2.2.1 列表推 ...
- Struts,Spring,Hibernate优缺点
Struts跟Tomcat.Turbine等诸 多Apache项目一样,是开源软件,这是它的一大优点.使开发者能更深入的了解其内部实现机制. Struts开放源码框架的创建是为了使开发者在构建基于Ja ...
- 001-ant design安装及快速入门【基于纯antd的基本项目搭建】
一.安装使用 1.1.安装 推荐使用 npm 或 yarn 的方式进行开发 npm install antd --save yarn add antd 1.2.浏览器引入 在浏览器中使用 script ...
- [Axiom 3D]1.初识Axiom
1. 简介 The Axiom 3D Rendering Engine is a fully object oriented 3D graphics engine using C# and the . ...