Netty的并发编程实践4:线程安全类的应用

1415人阅读 评论(3) 收藏 举报
分类:

在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的线程池进行了封装和改造,但是,本质上仍然是利用了线程池和线程安全队列简化了多线程编程。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3498997次
    • 积分:52654
    • 等级:
    • 排名:第58名
    • 原创:1440篇
    • 转载:83篇
    • 译文:1篇
    • 评论:3461条
    博客专栏
    最新评论