一个Lambda引发的血案
作者:Ever_00
来源:https://www.jianshu.com/p/b302123532b4
背景
上周有小伙伴反馈zk连接很慢。整理出zk连接的关键逻辑如下:
public class ClientZkAgent {//单例模式private static final ClientZkAgent instance = new ClientZkAgent();private ZooKeeper zk; //zk客户端private ClientZkAgent() {connect(); //初始化并连接zk}public static ClientZkAgent getInstance() {return instance;}/*** zk常用模式: 由于zookeeper的连接是异步的,为防止zk对象在建立有效连接之前就返回,* 我们阻塞主线程,并通过zookeeper的EventThread在连接事件中唤醒主线程*/private void connect() {CountDownLatch semaphore = new CountDownLatch(1);zk = new ZooKeeper(zkHost, timeout, watchEvent -> { // #_1switch (e.getState()) {case SyncConnected:semaphore.countDown();break;// 其它逻辑 ....}});semaphore.await(10000, TimeUnit.MILLISECONDS);}
}
分析
在本地重现后,通过jstack获得系统停滞期间的线程栈,发现这个时候zookeeper的EventThread有个比较奇怪的现象:
"main-EventThread" #13 daemon prio=5 os_prio=0 tid=0x000000001fe36800 nid=0xf0c in Object.wait() [0x000000002032f000]java.lang.Thread.State: RUNNABLEat com.github.dapeng.registry.zookeeper.ClientZkAgent.lambda$connect$0(ClientZkAgent.java:154)at com.github.dapeng.registry.zookeeper.ClientZkAgent$$Lambda$1/116211441.process(Unknown Source)at org.apache.zookeeper.ClientCnxn$EventThread.processEvent(ClientCnxn.java:533)at org.apache.zookeeper.ClientCnxn$EventThread.run(ClientCnxn.java:508)Locked ownable synchronizers:- None
客户端实际上很快就连上了zookeeper并返回后生成了
SyncConnected事件,而且EventThread已经在回调atcher.process方法了,但似乎事件线程就一直hold在上面#_1的位置无法往下走, 同时,lambda表达式变成了ClientZkAgent的一个方法了:lambda$connect$0。
了解了一下Java中lambda的实现方式,事情水落石出了。
简而言之,jvm会把lambda表达式转换成所在类的一个方法lambda${method}${seq}(method为该 所在的方法名,例如上面的connect方法),同时通过动态代理生成一个代理类(该代理类实现了lambda表达式所代表的具体接口),在该代理类中调用lambda${method}${seq}。
final class ClientZkAgent$$Lambda$1 implements Watcher {final ClientZkAgent clientZkAgent;public void process(WatchedEvent event) {clientZkAgent.lambda$connect$0(event);}
}
再梳理一下:
业务线程:
SyncConnected事件触发后,调用ClientZkAgent.lambda$connect$0(event), 试图唤醒业务线程(唤醒逻辑在lambda中)。
可见,在这个过程中,两个线程相互等待(类似死锁但不是死锁),直至业务线程超时后才化解这个局面。
解决
修改ClientZkAgent的初始化逻辑如下:
public class ClientZkAgent {//单例模式private static final ClientZkAgent instance = new ClientZkAgent();private ZooKeeper zk; //zk客户端private ClientZkAgent() {}public static ClientZkAgent getInstance() {if (instance.zk == null) {synchronized(ClientZkAgent.class) {if (instance.zk == null) {instance.connect();}}}return instance;}
正文结束
1.
2.
3.
4.
5.
6.
7.
8.
一个人学习、工作很迷茫?
点击「阅读原文」加入我们的小圈子!
一个Lambda引发的血案相关推荐
- 『转』度百死去飞秋一个BUG引发的血案
作了一篇文章度百死去飞秋一个BUG引发的血案,昨天,度百死去的美国客户发邮件给我,说我的软件出问题了,我查来查去,发现居然是服务器上一个目录无法删除,一删除就报 cannot read from th ...
- 【Elasticsearch】es 一个数据精度引发的血案
1.概述 在看博客的时候,发现有个博客 一个数据精度引发的血案 上面说,数据精度会丢失,然后我在 7.8.0版本的es测试,发现数据没有丢失. POST /index-lcc-0002/_doc {& ...
- ”一个馒头引发的血案“|记Mybatis之BindingException异常的产生及解决过程
一. 业务场景 前几天壹哥带学生做一个项目,需要更新数据库中的车辆信息表,具体需求是要根据指定车辆的设备id(编号和设备ID均非主键)来更新车辆信息.壹哥要求学生们用Mybatis进行实现,所以就在对 ...
- 一个馒头引发的血案...请看完无极后观看此片,保笑死人不偿命
一个馒头引发的血案... 采用搞笑的手法拍摄的,笑到你喷饭,极大的讽刺无极 下载地址:点击下载
- 摘要: Druid连接池一个设置引发的血案 -- 链接池出现问题
摘要: Druid连接池一个设置引发的血案 今天在一台配置很低的机器上运行批量更新的程序~~~ 大概跑了三十分钟~~~这配置~~~这程序~~~ 然后华丽丽的报异常了~~~ 具体异常是这样的, DEBU ...
- 一个随机数引发的血案
一个随机数引发的血案 我也来做一次标题党 原文地址:http://blog.csdn.net/WinsenJiansbomber/article/details/50604653 目录 一个随机数引发 ...
- 线上 CPU100% 异常案例:一个正则表达式引发的血案
前几天线上一个项目监控信息突然报告异常,上到机器上后查看相关资源的使用情况,发现 CPU 利用率将近 100%.通过 Java 自带的线程 Dump 工具,我们导出了出问题的堆栈信息. 我们可以看到所 ...
- 一个NODE_ENV 引发的血案
1 表象 控制台报错 截图没有完整的截下来,其实右边行号并没有具体的行号, 显示为payment-809e8ff.js 1 很明显 这是 js语法错误 但是当点击开里面显示的是html内容 第一行的 ...
- 一个“alert” 引发的血案
0 在还没有掌握全部证据之前就下结论会犯严重的错误,会使判断带有偏见.--<血字的研究> "齐识,路老板又来邮件了."白娜一脸无耐地说. "一定没好事吧?&q ...
- 一个域名引发的血案……
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云 发表于云+社区专栏 你在沙发上看世界杯,黑客在做什么? 深夜,当电视机屏幕上那个小小的足球牵动着亿万人的心弦时,猜一猜黑客 ...
最新文章
- Linux命令之 —— grep \ls \ ll \ sed \ bg fg \ ipset \ wc \ ifconfig \ awk
- 与Netflix合作 美电视运营商推出4K频道
- 6/100. Invert Binary Tree
- java中find方法_Java Document.find方法代码示例
- codeforces 122A-C语言解题报告
- 只能是做的HTML5审批流项目
- mysql error 1130 hy000:Host ‘localhost‘ is not allowed to connect to this mysql server 解决方案
- Access安全性之QA详解
- 怎么将tflite部署在安卓上_手把手教程:如何从零开始训练 TF 模型并在安卓系统上运行...
- Win下Eclipse提交hadoop程序出错:org.apache.hadoop.security.AccessControlException: Permission denied: user=
- 如何下载飞思卡尔单片机的S19文件
- 黑科技神器-uTools,必须下载
- 可能是求质数最高效的算法
- selenium点击爬取豆瓣高分电影
- blowfish java_blowfish加密算法
- 智慧城市不是建设出来的,而是运营出来的
- Scout - 可扩展的服务器和应用监控服务
- 光谱分布、光谱辐射通量密度与不同时间段分布光谱(图示)
- Broadcast 和 BroadcastReceiver
- 绝对的内幕!近些年各大IT公司售前薪水