Netty的并发编程实践4:线程安全类的应用
在JDK1.5的发行版本中,Java平台新增了java.util.concurrent,这个包中提供了一系列的线程安全集合、容器和线程池,利用这些新的线程安全类可以极大地降低Java多线程编程的难度,提升开发效率。
新的并发编程包中的工具可以分为如下4类。
◎ 线程池Executor Framework以及定时任务相关的类库,包括Timer等。
◎ 并发集合,包括List、Queue、Map和Set等。
◎ 新的同步器,例如读写锁ReadWriteLock等。
◎ 新的原子包装类,例如AtomicInteger等。
在实际编码过程中,我们建议通过使用线程池、Task(Runnable/Callable)、原子类和线程安全容器来代替传统的同步锁、wait和notify,以提升并发访问的性能、降低多线程编程的难度。
下面,针对新的线程并发包在Netty中的应用进行分析和说明,以期为大家的学习和应用提供指导。
首先看下线程安全容器在Netty中的应用。NioEventLoop是I/O线程,负责网络读写操作,同时也执行一些非I/O的任务。例如事件通知、定时任务执行等,因此,它需要一个任务队列来缓存这些Task。它的任务队列定义如图21-12所示。
图21-12 线程任务队列定义
它是一个ConcurrentLinkedQueue,我们看它的API说明,如图21-13所示。
图21-13 ConcurrentLinkedQueue线程安全文档
DOC文档明确说明这个类是线程安全的,因此,对它进行读写操作不需要加锁。下面我们继续看下队列中增加一个任务,如图21-14所示。
图21-14 ConcurrentLinkedQueue新增Task
读取任务,也不需要加锁,如图21-15所示。
图21-15 ConcurrentLinkedQueue读取Task
JDK的线程安全容器底层采用了CAS、volatile和ReadWriteLock实现,相比于传统重量级的同步锁,采用了更轻量、细粒度的锁,因此,性能会更高。合理地应用这些线程安全容器,不仅能提升多线程并发访问的性能,还能降低开发难度。
下面我们看看线程池在Netty中的应用,打开SingleThreadEventExecutor看它是如何定义和使用线程池的。
首先定义了一个标准的线程池用于执行任务,代码如下。
接着对它赋值并且进行初始化操作,代码如下。
执行任务代码如图21-16所示。
图21-16 SingleThreadEventExecutor任务执行
我们发现,实际上执行任务就是先把任务加入到任务队列中,然后判断线程是否已经启动循环执行,如果不是则需要启动线程。启动线程代码如图21-17所示。
实际上就是执行当前线程的run方法,循环从任务队列中获取Task并执行,我们看它的子类NioEventLoop的run方法就能一目了然,如图21-18所示。
如图21-19中框线内所示,循环从任务队列中获取任务并执行。
图21-17 SingleThreadEventExecutor启动新的线程
图21-18 按照I/O任务比例执行任务Task
图21-19 循环从任务队列中获取任务Task并执行
Netty对JDK的线程池进行了封装和改造,但是,本质上仍然是利用了线程池和线程安全队列简化了多线程编程。
Netty的并发编程实践4:线程安全类的应用的更多相关文章
- Netty的并发编程实践5:不要依赖线程优先级
当有多个线程同时运行的时候,由线程调度器来决定哪些线程运行.哪些等待以及线程切换的时间点,由于各个操作系统的线程调度器实现大相径庭,因此,依赖JDK自带的线程优先级来设置线程优先级策略的方法是错误和非 ...
- Netty的并发编程实践2:volatile的正确使用
长久以来大家对于volatile如何正确使用有很多的争议,既便是一些经验丰富的Java设计师,对于volatile和多线程编程的认识仍然存在误区.其实,volatile的使用非常简单,只要理解了Jav ...
- Netty的并发编程实践1:正确使用锁
很多刚接触多线程编程的开发者,虽然意识到了并发访问可变变量需要加锁,但是对于锁的范围.加锁的时机和锁的协同缺乏认识,往往会导致出现一些问题.下面笔者就结合Netty的代码来讲解下这方面的知识. 打开F ...
- Netty的并发编程实践3:CAS指令和原子类
互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能的额外损耗,因此这种同步被称为阻塞同步,它属于一种悲观的并发策略,我们称之为悲观锁.随着硬件和操作系统指令集的发展和优化,产生了非阻塞同步,被称为 ...
- [Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性
依据<Java并发编程实践>一书整理的思维导图.
- 并发编程实践五:ReentrantLock
ReentrantLock是一个可重入的相互排斥锁,实现了接口Lock,和synchronized相比,它们提供了同样的功能.但ReentrantLock使用更灵活.功能更强大,也更复杂.这篇文章将为 ...
- 并发编程实践三:Condition
Condition实例始终被绑定到一个锁(Lock)上.Lock替代了Java的synchronized方法,而Condition则替代了Object的监视器方法,包含wait.notify和noti ...
- 【Java并发编程六】线程池
一.概述 在执行并发任务时,我们可以把任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程,只要池里有空闲的线程,任务就会分配一个线程执行.在线程池的内部,任务被插入一个阻塞队列(Blo ...
- Java并发编程实践
最近阅读了<Java并发编程实践>这本书,总结了一下几个相关的知识点. 线程安全 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任 ...
随机推荐
- git修改最后一次commit的内容
提交修改 $ git add test.txt $ git commit -m "提交test.txt文件" 修改注释说明 如果需要修改commit的注释说明,则执行以下命令: $ ...
- jQuery应用操作之---表格
示例: <table> <thread> <tr><th>姓名</th><th>性别</th><th>暂 ...
- 解决在Ubuntu系统下用matplotlib作图时出现中文乱码问题
今天在jupyter notebook中画图时,中文不能正常显示,如下图所示: 在此记录一下解决的办法. 1.找到matplotlib配置文件的位置 import matplotlib print(m ...
- javascript中的BOM对象
1.window对象 所有的浏览器都支持window对象 概念上讲,一个html文档对应一个window对象 功能上讲,控制浏览器窗口 使用上讲,window对象不需要创建对象,直接使用 2.wind ...
- 让windows系统的DOS窗口也可以显示utf8字符集
C:\Users\Administrator>chcp活动代码页: 936 windows cmd命令显示UTF8设置 在中文Windows系统中,如果一个文本文件是UTF-8编码的,那么在CM ...
- .NET图表控件(LightningChart )的用法
概述 LightningChart (LightningChart Ultimate) 软件开发工具包是微软Visual Studio 的一个插件,专攻大数据可视化呈现问题,用于 WPF(Window ...
- python进行各类API的使用
前言: 献上歌曲一首: 因为快要上学了,昨天晚上熬夜.然后今天早上起床 没有什么精神.吃完午饭后开始思考今天写什么好呢 然后逛着逛着逛到了一个API网站.感觉还不错就爬了 0x01: 环境:windo ...
- php+redis 学习 二 悲观锁
<?php header('content-type:text/html;chaeset=utf-8'); /** * redis实战 * * 实现悲观锁机制 * */ $timeout = 5 ...
- smallcorgi/Faster-RCNN_TF训练自己的数据
熟悉了github项目提供的训练测试后,可以来训练自己的数据了.本文只介绍改动最少的方法,只训练2个类, 即自己添加的类(如person)和 background,使用的数据格式为pascal_voc ...
- CometD的消息推送
CometD 框架 CometD 框架是基于 HTTP 的事件驱动通信解决方案.CometD 框架提供了一个 Java 服务器部件和一个 Java 客户端部件,还有一个基于 jQuery 和 Dojo ...