Netty : writeAndFlush的线程安全及并发问题
使用Netty编程时,我们经常会从用户线程,而不是Netty线程池发起write操作,因为我们不能在netty的事件回调中做大量耗时操作。那么问题来了 –
1, writeAndFlush是线程安全的吗?
2, 是否使用了锁,导致并发性能下降呢
我们来看代码 – 在DefaultChannelHandlerContext中
@Override
public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
DefaultChannelHandlerContext next;
next = findContextOutbound(MASK_WRITE);
ReferenceCountUtil.touch(msg, next);
next.invoker.invokeWrite(next, msg, promise);
next = findContextOutbound(MASK_FLUSH);
next.invoker.invokeFlush(next);
return promise;
}
在DefaultChannelHandlerInvoker.java中
@Override
public void invokeWrite(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
if (msg == null) {
throw new NullPointerException("msg");
}
if (!validatePromise(ctx, promise, true)) {
// promise cancelled
ReferenceCountUtil.release(msg);
return;
} if (executor.inEventLoop()) {
invokeWriteNow(ctx, msg, promise);
} else {
AbstractChannel channel = (AbstractChannel) ctx.channel();
int size = channel.estimatorHandle().size(msg);
if (size > 0) {
ChannelOutboundBuffer buffer = channel.unsafe().outboundBuffer();
// Check for null as it may be set to null if the channel is closed already
if (buffer != null) {
buffer.incrementPendingOutboundBytes(size);
}
}
safeExecuteOutbound(WriteTask.newInstance(ctx, msg, size, promise), promise, msg);
}
}
private void safeExecuteOutbound(Runnable task, ChannelPromise promise, Object msg) {
try {
executor.execute(task);
} catch (Throwable cause) {
try {
promise.setFailure(cause);
} finally {
ReferenceCountUtil.release(msg);
}
}
}
可见,writeAndFlush如果在Netty线程池内执行,则是直接write;否则,将作为一个task插入到Netty线程池执行。
《Netty权威指南》写到
通过调用NioEventLoop的execute(Runnable task)方法实现,Netty有很多系统Task,创建他们的主要原因是:当I/O线程和用户线程同时操作网络资源时,为了防止并发操作导致的锁竞争,将用户线程的操作封装成Task放入消息队列中,由I/O线程负责执行,这样就实现了局部无锁化。
参考
http://www.cnblogs.com/zemliu/p/3667332.html
http://netty.io/5.0/xref/io/netty/channel/DefaultChannelHandlerInvoker.html
http://www.infoq.com/cn/articles/netty-version-upgrade-history-thread-part/
Netty : writeAndFlush的线程安全及并发问题的更多相关文章
- (转)Netty : writeAndFlush的线程安全及并发问题
rocketmq用netty实现的网络连接,发现它多个线程掉用一个channel连接,所以这个是线程安全的? 使用Netty编程时,我们经常会从用户线程,而不是Netty线程池发起write操作,因为 ...
- Netty writeAndFlush() 流程与异步
Netty writeAndFlush()方法分为两步, 先 write 再 flush @Override public ChannelFuture writeAndFlush(Object msg ...
- 设计模式:基于线程池的并发Visitor模式
1.前言 第二篇设计模式的文章我们谈谈Visitor模式. 当然,不是简单的列个的demo,我们以电商网站中的购物车功能为背景,使用线程池实现并发的Visitor模式,并聊聊其中的几个关键点. 一,基 ...
- java线程安全之并发Queue
关闭 原 java线程安全之并发Queue(十三) 2017年11月19日 23:40:23 小彬彬~ 阅读数:12092更多 所属专栏: 线程安全 版权声明:本文为博主原创文章,未经博主允许不 ...
- 性能测试:深入理解线程数,并发量,TPS,看这一篇就够了
并发数,线程数,吞吐量,每秒事务数(TPS)都是性能测试领域非常关键的数据和指标. 那么他们之间究竟是怎样的一个对应关系和内在联系? 测试时,我们经常容易将线程数等同于表述为并发数,这一表述正确吗? ...
- 文件数据库sqlite3 C++ 线程安全和并发
转载:https://www.cnblogs.com/feng9exe/p/10682567.html(线程安全和并发) 转载:https://juejin.im/post/5b7d8522e51d4 ...
- 如何理解 jmeter 的线程数与并发数之间的关系
https://blog.csdn.net/weixin_39955351/article/details/110548162 多个线程组的并发是如何计算的?
- websocket(三) 进阶!netty框架实现websocket达到高并发
引言: 在前面两篇文章中,我们对原生websocket进行了了解,且用demo来简单的讲解了其用法.但是在实际项目中,那样的用法是不可取的,理由是tomcat对高并发的支持不怎么好,特别是tomcat ...
- websocket 进阶!netty框架实现websocket达到高并发
引言: 在前面两篇文章中,我们对原生websocket进行了了解,且用demo来简单的讲解了其用法.但是在实际项目中,那样的用法是不可取的,理由是tomcat对高并发的支持不怎么好,特别是tomcat ...
随机推荐
- ActionListener的三种实现方法
Swing是目前Java中不可缺少的窗口工具组,是用户建立图形化用户界面(GUI)程序的 强大工具.Java Swing组件自动产生各种事件来响应用户行为.如当用户点击按钮或选择菜单项目时,Swing ...
- css中很有用的属性
有些css属性很实用,但不常用也就被忘记. 这里纪录了自己在项目中用过的一些. html,body{ -webkit-tap-highlight-color:transparent; } 这个的用途是 ...
- ui-grid
html代码: <html ng-app="myApp"> <head> <meta charset="utf- ...
- CentOS下使用Postfix + Dovecot + Dnsmasq搭建极简局域网邮件系统
背景 开发环境为局域网,工作内容需要经常查看邮件文件(*.eml),可恶的Foxmail必须验证账户才能进入主界面,才能打开eml文件查看. 无奈搭一个局域网内的邮件系统吧.极简搭建,仅用于通过Fox ...
- ASP.NET Identity - LockoutEnabled
LockoutEnabled 并不是想象中的 用户是否 锁定. 而是 LockoutEnabled 标示 登陆是否此用户要检查 LockoutEndDateUtc字段. 如果为true则判断Locko ...
- Frameset框架优缺点--来自新浪微博
原文地址:http://blog.sina.com.cn/s/blog_4a4b1b010100p6ro.html HTML框架简述 一个浏览器窗体可以通过几个页面的组合来显示.我们可以使用框架来 ...
- VR原理讲解及开发入门
本文是作者obuil根据多年心得专门为想要入门的VR开发者所写,由52VR网站提供支持. 1. VR沉浸感和交互作用产生的原理: 在之前,我们观看一个虚拟的创造内容是通过平面显示器的,52VR ...
- C语言第六次作业
#include <stdio.h> int main() { ; printf("输入几个数:"); scanf("%d",&n); ;i ...
- [原创]java WEB学习笔记105:Spring学习---AOP介绍,相关概念,使用AOP,利用 方法签名 编写 AspectJ 切入点表达式
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 在SublimeText上搭建ReactJS开发环境(转载)
本文转载自: http://blog.csdn.net/yczz/article/details/50469388