google Guava包的ListenableFuture解析

原文地址  译者:罗立树  校对:方腾飞

并发编程是一个难题,但是一个强大而简单的抽象可以显著的简化并发的编写。出于这样的考虑,Guava 定义了 ListenableFuture接口并继承了JDK concurrent包下的Future 接口。

我们强烈地建议你在代码中多使用ListenableFuture来代替JDK的 Future, 因为:

  • 大多数Futures 方法中需要它。
  • 转到ListenableFuture 编程比较容易。
  • Guava提供的通用公共类封装了公共的操作方方法,不需要提供Future和ListenableFuture的扩展方法。
    Read more

《C++ Concurrency in Action》中文版

Snip20131231_6
2014年马上就到了,借此文感谢各位同学一直以来对并发编程网的支持和厚爱,祝大家新年快乐,并在新的一年里事事马到成功!在新的一年里如果您对并发编程网有什么要求,请只管在本文的回复里告诉我们。

至此新春之际,并发网和人民邮电出版社将在2014年向大家推送《C++ Concurrency in Action》中文版的样章,该书即将登场,而并发编程网让大家先睹为快!本文是第一篇,主要是包含本书的内容介绍,目录和译者介绍。喜欢的话请猛点赞。
Read more

您还有心跳吗?超时机制分析

问题描述

在C/S模式中,有时我们会长时间保持一个连接,以避免频繁地建立连接,但同时,一般会有一个超时时间,在这个时间内没发起任何请求的连接会被断开,以减少负载,节约资源。并且该机制一般都是在服务端实现,因为client强制关闭或意外断开连接,server端在此刻是感知不到的,如果放到client端实现,在上述情况下,该超时机制就失效了。本来这问题很普通,不太值得一提,但最近在项目中看到了该机制的一种糟糕的实现,故在此深入分析一下。 Read more

测试并发应用(六)用 FindBugs 分析并发代码

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

用 FindBugs 分析并发代码

静态代码分析工具是一套通过分析应用源代码来查找潜在异常的工具。这些工具,例如 Checkstyle, PMD, 或者 FindBugs,他们有定义极好的实践(good practices) 规则,然后解析源代码来查找有没有违反这些规则。目的是在产品运行之前,更早的找到异常或者修改较差性能的代码。各种编程语言通常提供这样的工具,Java也不例外。分析Java代码的工具之一是 FindBugs。 它是开发资源工具,包含了一系列的规则来分析 Java concurrent 代码。

在这个指南,你将学习如何使用工具来分析你的 Java concurrent 应用。 Read more

聊聊并发(八)——Fork/Join框架介绍

本文首发于InfoQ

1. 什么是Fork/Join框架

Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

我们再通过Fork和Join这两个单词来理解下Fork/Join框架,Fork就是把一个大任务切分为若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结果。比如计算1+2+。。+10000,可以分割成10个子任务,每个子任务分别对1000个数进行求和,最终汇总这10个子任务的结果。Fork/Join的运行流程图如下:


Read more

ReentrantLock(重入锁)以及公平性

Dedicate to Molly.

简介

ReentrantLock的实现不仅可以替代隐式的synchronized关键字,而且能够提供超过关键字本身的多种功能。
这里提到一个锁获取的公平性问题,如果在绝对时间上,先对锁进行获取的请求一定被先满足,那么这个锁是公平的,反之,是不公平的,也就是说等待时间最长的线程最有机会获取锁,也可以说锁的获取是有序的。ReentrantLock这个锁提供了一个构造函数,能够控制这个锁是否是公平的。
而锁的名字也是说明了这个锁具备了重复进入的可能,也就是说能够让当前线程多次的进行对锁的获取操作,这样的最大次数限制是Integer.MAX_VALUE,约21亿次左右。
事实上公平的锁机制往往没有非公平的效率高,因为公平的获取锁没有考虑到操作系统对线程的调度因素,这样造成JVM对于等待中的线程调度次序和操作系统对线程的调度之间的不匹配。对于锁的快速且重复的获取过程中,连续获取的概率是非常高的,而公平锁会压制这种情况,虽然公平性得以保障,但是响应比却下降了,但是并不是任何场景都是以TPS作为唯一指标的,因为公平锁能够减少“饥饿”发生的概率,等待越久的请求越是能够得到优先满足。
Read more

聊聊并发(七)——Java中的阻塞队列

原文首发于InfoQ

1. 什么是阻塞队列?

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。
Read more

基于锁的原子操作

本文翻译自《英特尔® 64 和 IA-32 架构软件开发人员手册》卷三”系统编程指南”的第八章”多处理器的管理”的第一节 译者:方腾飞

8.1 基于锁的原子操作

32位IA-32处理器的系统内存地址支持基于锁的原子操作。这些操作通常用于管理共享的数据结构(如信号量,段描述符,系统段,或页表),在这些数据结构里,两个或多个处理器可以尝试同时修改相同的字段或标志。处理器使用三个相互关联的机制来实现基于锁的原子操作:

  1. 保证在单处理器下该操作是原子操作。
  2. 总线锁定,使用LOCK#信号和LOCK指令前缀。
  3. IMEI(高速缓存一致性)协议,以确保缓存的数据结构(高速缓存锁定)可以进行原子操作,这个机制是在奔腾4,英特尔至强和P6系列处理器。 Read more

测试并发应用(五) 编写有效的日志

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

写有效的日志

log工具提供了允许你写信息到一个或者多个目的地的机制。一个Logger是由以下这些组成:

  • 一个或多个处理者: 一个处理者将决定目的地和log信息的格式。你可以把日志信息写入操控台,文档,或者数据库。
  • 名字: 通常Logger使用的名字是基于类名或者它的包名。
  • 等级: 日志信息有等级来表明它的重要性。Logger也有个等级是用来决定写什么样的信息。它只会写和这个等级一样重要的,或者更重要的信息。

为了以下2个主要目的,你应该使用log 系统:

  • 当异常被捕捉,写尽可能多的信息。这个会帮助你定位错误并解决它。
  • 写关于程序正在执行的类和方法的信息。 Read more

测试并发应用(四)监控Fork/Join池

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

监控Fork/Join池

Executor 框架提供了线程的创建和管理,来实现任务的执行机制。Java 7 包括了一个 Executor 框架的延伸为了一种特别的问题而使用的,将比其他解决方案的表现有所提升(可以直接使用 Thread 对象或者 Executor 框架)。它是 Fork/Join 框架。

此框架是为了解决可以使用 divide 和 conquer 技术,使用 fork() 和 join() 操作把任务分成小块的问题而设计的。主要的类实现这个行为的是 ForkJoinPool 类。

在这个指南,你将学习从ForkJoinPool类可以获取的信息和如何获取这些信息。 Read more

Netty源码解读(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的“梦境”概念,希望大家喜欢。

Read more

多线程排序性能优化比赛分享-如何赢得一个机械键盘

第一届淘宝并发编程比赛(多线程排序性能优化)冠军是颜然同学。

以下是他的代码:

https://github.com/hanfoo/WordSorterMatch

以下是他分享的PPT:

如何赢一个机械键盘.pptx

测试并发应用(三)监控Executor框架

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

监控Executor框架

Executor 框架提供从线程的创建和管理来分别实现任务来执行这些任务的机制。如果你使用一个执行者,你只需要实现 Runnable 对象并把他们发送给执行者。 执行者的责任是管理线程。当你发一个任务给执行者,它会尝试使用pooled线程来执行这个任务,来避免创建新的任务。此机制由 Executor 接口提供,它是以 ThreadPoolExecutor 类来实现的。

在这个指南,你将学习从ThreadPoolExecutor执行者可以获取的信息和如何获取这些信息。 Read more

happens-before俗解

学习Java并发,到后面总会接触到happens-before偏序关系。初接触玩意儿简直就是不知所云,下面是经过一段时间折腾后个人对此的一点浅薄理解,希望对初接触的人有帮助。如有不正确之处,欢迎指正。

synchronized、大部分锁,众所周知的一个功能就是使多个线程互斥/串行的(共享锁允许多个线程同时访问,如读锁)访问临界区,但他们的第二个功能 —— 保证变量的可见性 —— 常被遗忘。

为什么存在可见性问题?简单介绍下。相对于内存,CPU的速度是极高的,如果CPU需要存取数据时都直接与内存打交道,在存取过程中,CPU将一直空闲,这是一种极大的浪费,妈妈说,浪费是不好的,所以,现代的CPU里都有很多寄存器,多级cache,他们比内存的存取速度高多了。某个线程执行时,内存中的一份数据,会存在于该线程的工作存储中(working memory,是cache和寄存器的一个抽象,这个解释源于《Concurrent Programming in Java: Design Principles and Patterns, Second Edition》§2.2.7,原文:Every thread is defined to have a working memory (an abstraction of caches and registers) in which to store values. 有不少人觉得working memory是内存的某个部分,这可能是有些译作将working memory译为工作内存的缘故,为避免混淆,这里称其为工作存储,每个线程都有自己的工作存储),并在某个特定时候回写到内存。单线程时,这没有问题,如果是多线程要同时访问同一个变量呢?内存中一个变量会存在于多个工作存储中,线程1修改了变量a的值什么时候对线程2可见?此外,编译器或运行时为了效率可以在允许的时候对指令进行重排序,重排序后的执行顺序就与代码不一致了,这样线程2读取某个变量的时候线程1可能还没有进行写入操作呢,虽然代码顺序上写操作是在前面的。这就是可见性问题的由来。

Read more

第一届淘宝并发编程比赛-多线程排序性能优化

去年一粟在淘宝内部组织了第一届淘宝并发编程比赛。

具体比赛问题请移步这里:https://github.com/Skinney/WordSorter 查看。

里面已经有可运行的代码,在一粟的机器上(RMBP 2012: 2.7 GHz Intel Core i7)运行速度如下:

16:07:49 hugo-rmbp ~/Projects/hugozhu/WordSorter/Go $ go run main.go  128 sowpods.txt out.txt
WordSort finished in <strong>335 ms</strong>

16:07:19 hugo-rmbp ~/Projects/hugozhu/WordSorter/Java $ java Sort 128 sowpods.txt out.txt
Loading contents of sowpods.txt... 170ms
Sorting... 222ms
Writing results to out.txt... 135ms

Using 128 threads, 267751 words was sorted in <strong>528</strong> milliseconds.

Java落后很多, 但看实现I/O部分耗费了一半多的时间,我们可以来优化一下Java实现:提高一下I/O性能,或者试一下Fork/Join框架,请大家都试试,把优化结果贴上来比较。 Read more

return top