定制并发类(三)实现一个基于优先级的Executor类

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉

实现一个基于优先级的Executor类

在Java并发API的第一个版本中,你必须创建和运行应用程序中的所有线程。在Java版本5中,随着执行者框架(Executor framework)的出现,对于并发任务的执行,一个新的机制被引进。

使用执行者框架(Executor framework),你只要实现你的任务并把它们提交给执行者。这个执行者负责执行你的任务的线程的创建和执行。

在内部,一个执行者使用一个阻塞队列来存储待处理任务。以任务到达执行者的顺序来存储。一个可能的替代就是使用一个优先级列队来存储新的任务。这样,如果一个高优先级的新任务到达执行者,它将比其他已经在等待一个线程来执行它们,且低优先级的任务先执行。

在这个指南中,你将学习如何实现一个执行者,它将使用优先级队列来存储你提交执行的任务。

阅读全文

定制并发类(二)定制ThreadPoolExecutor类

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉

定制ThreadPoolExecutor类

执行者框架(Executor framework)是一种机制,允许你将线程的创建与执行分离。它是基于Executor和ExecutorService接口及其实现这两个接口的ThreadPoolExecutor类。它有一个内部的线程池和提供允许你提交两种任务给线程池执行的方法。这些任务是:

  • Runnable接口,实现没有返回结果的任务
  • Callable接口,实现返回结果的任务

在这两种情况下,你只有提交任务给执行者。这个执行者使用线程池中的线程或创建一个新的线程来执行这些任务。执行者同样决定任务被执行的时刻。

在这个指南中,你将学习如何覆盖ThreadPoolExecutor类的一些方法,计算你在执行者中执行的任务的执行时间,并且将关于执行者完成它的执行的统计信息写入到控制台。

阅读全文

定制并发类(一)引言

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉 

在这个文章中,我们将包含:

引言

Java 并发API提供许多接口和类来实现并发应用程序。它们提供底层(low-level)机制,如Thread类、Runnable或Callable接口、或synchronized关键字。同样也提供高级(high-level)机制,如Executor框架和Java 7 发布的Fork/Join框架。尽管这样,你可能发现你自己开发一个程序时,没有一个java类能满足你的需求。
阅读全文

定制并发类(十一)实现自定义的原子对象

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

实现你自己的原子(atomic)对象

Java版本5中引入原子变量,并提供对单个变量的原子操作。当一个线程在原子变量上执行操作时,这个类的实现包含一种机制用来检查这个操作在一个步骤内完成。基本上,这个操作是先获取变量的值,然后在本地变量中改变这个值,最后尝试将旧值变成这个新值。如果旧值仍然是相同的,它将改变成新值,否则,这个方法重新开始这个操作。(校对注:这段话描述了CAS的实现原理 )

在这个指南中,你将学习如何继承一个原子对象和如何实现遵从原子对象机制的两个操作,来保证所有的操作在一个步骤内完成。 阅读全文

并发集合(八)使用原子变量

声明:本文是《 Java 7 Concurrency Cookbook 》的第一章, 作者: Javier Fernández González 译者:郑玉婷 校对:方腾飞

在Java 1.5中就引入了原子变量,它提供对单个变量的原子操作。当你在操作一个普通变量时,你在Java实现的每个操作,在程序编译时会被转换成几个机器能读懂的指令。例如,当你分配一个值给变量,在Java你只使用了一个指令,但是当你编译这个程序时,这个指令就被转换成多个JVM 语言指令。这样子的话当你在操作多个线程且共享一个变量时,就会导致数据不一致的错误。

为了避免这样的问题,Java引入了原子变量。当一个线程正在操作一个原子变量时,即使其他线程也想要操作这个变量,类的实现中含有一个检查那步骤操作是否完成的机制。 基本上,操作获取变量的值,改变本地变量值,然后尝试以新值代替旧值。如果旧值还是一样,那么就改变它。如果不一样,方法再次开始操作。这个操作称为 Compare and Set(校对注:简称CAS,比较并交换的意思)。
阅读全文

并发集合(七)创建并发随机数

声明:本文是《 Java 7 Concurrency Cookbook 》的第六章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

创建并发随机数

Java并发API提供指定的类在并发应用程序中生成伪随机。它是ThreadLocalRandom类,这是Java 7版本中的新类。它使用线程局部变量。每个线程希望以不同的生成器生成随机数,但它们是来自相同类的管理,这对程序员是透明的。在这种机制下,你将获得比使用共享的Random对象为所有线程生成随机数更好的性能。

在这个指南中,你将学习如何在并发应用程序中使用ThreadLocalRandom生成随机数。

阅读全文

并发集合(六)使用线程安全的NavigableMap

声明:本文是《 Java 7 Concurrency Cookbook 》的第六章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

使用线程安全的NavigableMap

Java API 提供的有趣的数据结构,并且你可以在并发应用程序中使用,它就是ConcurrentNavigableMap接口的定义。实现ConcurrentNavigableMap接口的类存储以下两部分元素:

  • 唯一标识元素的key
  • 定义元素的剩余数据

每部分在不同的类中实现。

Java API 也提供了这个接口的实现类,这个类是ConcurrentSkipListMap,它实现了非阻塞列表且拥有ConcurrentNavigableMap的行为。在内部实现中,它使用Skip List来存储数据。Skip List是基于并行列表的数据结构,它允许我们获取类似二叉树的效率。使用它,你可以得到一个排序的数据结构,这比排序数列使用更短的访问时间来插入、搜索和删除元素。

注意:在1990年,由William Pugh引入Skip List。

当你往map中插入数据时,它使用key来排序它们,所以,所有元素将是有序的。除了返回具体的元素,这个类也提供了获取map的子map的方法。 阅读全文

并发集合(五)使用线程安全的、带有延迟元素的列表

声明:本文是《 Java 7 Concurrency Cookbook 》的第六章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

使用线程安全的、带有延迟元素的列表

DelayedQueue类是Java API提供的一种有趣的数据结构,并且你可以用在并发应用程序中。在这个类中,你可以存储带有激活日期的元素。方法返回或抽取队列的元素将忽略未到期的数据元素。它们对这些方法来说是看不见的。

为了获取这种行为,你想要存储到DelayedQueue类中的元素必须实现Delayed接口。这个接口允许你处理延迟对象,所以你将实现存储在DelayedQueue对象的激活日期,这个激活时期将作为对象的剩余时间,直到激活日期到来。这个接口强制实现以下两种方法:

  • compareTo(Delayed o):Delayed接口继承Comparable接口。如果执行这个方法的对象的延期小于作为参数传入的对象时,该方法返回一个小于0的值。如果执行这个方法的对象的延期大于作为参数传入的对象时,该方法返回一个大于0的值。如果这两个对象有相同的延期,该方法返回0。
  • getDelay(TimeUnit unit):该方法返回与此对象相关的剩余延迟时间,以给定的时间单位表示。TimeUnit类是一个枚举类,有以下常量:DAYS、HOURS、 MICROSECONDS、MILLISECONDS、 MINUTES、 NANOSECONDS 和 SECONDS。

阅读全文

并发集合(四)用优先级对使用阻塞线程安全的列表排序

声明:本文是《 Java 7 Concurrency Cookbook 》的第六章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

用优先级对使用阻塞线程安全的列表排序

一个典型的需求是,当你需要使用一个有序列表的数据结构时,Java提供的PriorityBlockingQueue类就拥有这种功能。

你想要添加到PriorityBlockingQueue中的所有元素必须实现Comparable接口。这个接口有一个compareTo()方法,它接收同样类型的对象,你有两个比较的对象:一个是执行这个方法的对象,另一个是作为参数接收的对象。如果本地对象小于参数,则该方法返回小于0的数值。如果本地对象大于参数,则该方法返回大于0的数值。如果本地对象等于参数,则该方法返回等于0的数值。 阅读全文

并发集合(三)使用阻塞线程安全的列表

声明:本文是《 Java 7 Concurrency Cookbook 》的第六章,作者: Javier Fernández González  译者:许巧辉

使用阻塞线程安全的列表

列表(list)是最基本的集合。一个列表中的元素数量是不确定的,并且你可以添加、读取和删除任意位置上的元素。并发列表允许不同的线程在同一时刻对列表里的元素进行添加或删除,而不会产生任何数据不一致的问题。

在这个指南中,你将学习如何在你的并发应用程序中使用阻塞的列表。阻塞列表与非阻塞列表的主要区别是,阻塞列表有添加和删除元素的方法,如果由于列表已满或为空而导致这些操作不能立即进行,它们将阻塞调用的线程,直到这些操作可以进行。Java包含实现阻塞列表的LinkedBlockingDeque类。

你将使用以下两种任务来实现例子:

  • 添加大量数据到列表。
  • 从同一个列表中删除大量的数据。

阅读全文

Netty源码解读(二)Netty中的buffer

感谢网友【黄亿华】投递本稿。

上一篇文章我们概要介绍了Netty的原理及结构,下面几篇文章我们开始对Netty的各个模块进行比较详细的分析。Netty的结构最底层是buffer模块,这部分也相对独立,我们就先从buffer讲起。

What: buffer二三事

buffer中文名又叫缓冲区,按照维基百科的解释,是”在数据传输时,在内存里开辟的一块临时保存数据的区域”。它其实是一种化同步为异步的机制,可以解决数据传输的速率不对等以及不稳定的问题。

阅读全文

Netty源码解读(一)概述

感谢网友【黄亿华】投递本稿。

Netty和Mina是Java世界非常知名的通讯框架。它们都出自同一个作者,Mina诞生略早,属于Apache基金会,而Netty开始在Jboss名下,后来出来自立门户netty.io。关于Mina已有@FrankHui的Mina系列文章,我正好最近也要做一些网络方面的开发,就研究一下Netty的源码,顺便分享出来了。 Netty目前有两个分支:4.x和3.x。4.0分支重写了很多东西,并对项目进行了分包,规模比较庞大,入手会困难一些,而3.x版本则已经被广泛使用。本系列文章针对netty 3.7.0 final。3.x和4.0的区别可以参考这篇文章:http://www.oschina.net/translate/netty-4-0-new-and-noteworthy?print阅读全文

并发集合(二)使用非阻塞线程安全的列表

声明:本文是《 Java 7 Concurrency Cookbook 》的第六章,作者: Javier Fernández González     译者:许巧辉

使用非阻塞线程安全的列表

列表(list)是最基本的集合。一个列表有不确定的元素数量,并且你可以添加、读取和删除任意位置上的元素。并发列表允许不同的线程在同一时刻对列表的元素进行添加或删除,而不会产生任何数据不一致(问题)。

在这个指南中,你将学习如何在你的并发应用程序中使用非阻塞列表。非阻塞列表提供这些操作:如果操作不能立即完成(比如,你想要获取列表的元素而列表却是空的),它将根据这个操作抛出异常或返回null值。Java 7引进实现了非阻塞并发列表的ConcurrentLinkedDeque类。

我们将使用以下两种不同任务来实现一个例子:

  • 大量添加数据到列表
  • 在同个列表中,大量删除数据

阅读全文

并发集合(一)引言

声明:本文是《 Java 7 Concurrency Cookbook 》的第六章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

在本章中,我们将包含:

引言

在编程中,数据结构是一种基本的元素。几乎每个程序都使用一个或多个数据结构类型来存储和管理它们的数据。Java API提供了Java集合框架(Java Collections framework),它包括可以用来实现许多不同的数据结构的接口、类和算法,你可以在程序中使用它们。

当你需要在并发程序中使用数据集合时,你必须十分小心的选择实现。大多数集合数并不适合用在并发应用程序中,因为它们没有控制并发访问数据。如果一些并发任务共享一个数据结构,而这个数据结构并不适合用在并发任务中,你将会有数据不一致的错误,这将影响到程序的正确运行。ArrayList类就是这种数据结构的一个例子。
阅读全文

基本线程同步(八)在Lock中使用多个条件

声明:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

在Lock中使用多个条件

一个锁可能伴随着多个条件。这些条件声明在Condition接口中。 这些条件的目的是允许线程拥有锁的控制并且检查条件是否为true,如果是false,那么线程将被阻塞,直到其他线程唤醒它们。Condition接口提供一种机制,阻塞一个线程和唤醒一个被阻塞的线程。

在并发编程中,生产者与消费者是经典的问题。我们有一个数据缓冲区,一个或多个数据生产者往缓冲区存储数据,一个或多个数据消费者从缓冲区中取出数据,正如在这一章中前面所解释的一样。

在这个指南中,你将学习如何通过使用锁和条件来实现生产者与消费者问题。 阅读全文

return top