标签 ‘ Concurrent

如何优雅的使用和理解线程池

前言

平时接触过多线程开发的童鞋应该都或多或少了解过线程池,之前发布的《阿里巴巴 Java 手册》里也有一条:

可见线程池的重要性。

简单来说使用线程池有以下几个目的:

  • 线程是稀缺资源,不能频繁的创建。
  • 解耦作用;线程的创建于执行完全分开,方便维护。
  • 应当将其放入一个池子中,可以给其他任务进行复用。

阅读全文

CompletableFuture 不能被中断

原文链接 作者:Tomasz Nurkiewicz  译者:simonwang

我之前写过一篇关于InterruptedException and interrupting threads的文章。总之,如果你调用Future.cancel(),那么Future不仅会终止正在等待的get(),还会试图去中断底层的线程。这是个很重要的特征,它能够使线程池变得更加利于使用。我在之前的文章中也说过,相对于标准的Future,尽量使用CompletableFuture。但事实证明,Future的更加强大的兄弟-CompletableFuture并不能优雅地处理cancel()。

阅读全文

Guava官方文档-RateLimiter类

原文链接 作者:Dimitris Andreou  译者:魏嘉鹏 校对:方腾飞token_bucket

RateLimiter 从概念上来讲,速率限制器会在可配置的速率下分配许可证。如果必要的话,每个acquire() 会阻塞当前线程直到许可证可用后获取该许可证。一旦获取到许可证,不需要再释放许可证。

校对注:RateLimiter使用的是一种叫令牌桶的流控算法,RateLimiter会按照一定的频率往桶里扔令牌,线程拿到令牌才能执行,比如你希望自己的应用程序QPS不要超过1000,那么RateLimiter设置1000的速率后,就会每秒往桶里扔1000个令牌。

[code lang=”java”]
com.google.common.util.concurrent.RateLimiter

@ThreadSafe
@Betapublic
abstract class RateLimiter extends Object
[/code]

阅读全文

并发性能优化 – 降低锁粒度

原文链接  作者:Adrianos Dadis 译者:买蓉(sky.mairong@gmail.com) 校对:方腾飞

在高负载多线程应用中性能是非常重要的。为了达到更好的性能,开发者必须意识到并发的重要性。当我们需要使用并发时, 常常有一个资源必须被两个或多个线程共享。

在这种情况下,就存在一个竞争条件,也就是其中一个线程可以得到锁(锁与特定资源绑定),其他想要得到锁的线程会被阻塞。这个同步机制的实现是有代价的,为了向你提供一个好用的同步模型,JVM和操作系统都要消耗资源。有三个最重要的因素使并发的实现会消耗大量资源,它们是:

  • 上下文切换
  • 内存同步
  • 阻塞

阅读全文

Harris’s Linked List

原文地址 作者:Pedro Ramalhete,译者:叶磊,校对:周可人

在学术论文中Harris Linked List是使用最广泛的并发数据结构之一。

Harris Linked List是一个基于linked-list的并发有序set(或者是map),可进行无锁性质的插入,删除和查找操作。

http://research.microsoft.com/pubs/67089/2001-disc.pdf

这篇文章最早在2001年的DISC会议上发表,作者是Tim Harris,目前在Oracle就职。

https://labs.oracle.com/pls/apex/f?p=labs:bio:0:296

阅读全文

Ticket Lock的Relaxed Atomics优化

原文地址 作者:Pedro Ramalhete,译者:周可人,校对:梁海舰

Tick lock是mutual lock的一种简单实现:

http://web.mit.edu/6.173/www/currentsemester/readings/R06-scalable-synchronization-1991.pdf

它是由John Mellor-Crummey和Michael Scott在1991年提出的(pdf中2.2节),感谢C++11和C11中新的内存模型,我们可以对单个变量进行具有屏障或者不具有屏障的原子操作。当屏障没有使用,只有原子性保证时,我们称之为“relaxed atomic”:

http://en.cppreference.com/w/cpp/atomic/memory_order

注意在C11/C++11内存模型中,一个原子变量并不具有内在的“顺序一致性”或者“relaxed”性质,然而我们可以在每次访问的时选择它的行为。

原子修饰符只能保证原子性,即这个变量会被单步读或写。其他语言,如Java和Scala则不同,它们可以保证几乎所有的原生类型提供原子性保证,从而表现为“relaxed atomic”。并且,所有被声明为顺序一致性的变量可以在整个程序中保持性质(除非在Java中使用sun.misc.unsafe)。尽管这个细微的差异可能看起来并不重要,但是当我们的目标是从同步或是并发算法中挖掘最大性能时,就需要关注这个差异了。

阅读全文

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

声明:本文是《 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类。

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

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

阅读全文

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

声明:本文是《 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类就是这种数据结构的一个例子。
阅读全文

return top