JAVA ’ 目录归档

Oracle官方并发教程之并发随机数

原文地址 译文地址 译者:李任 校对:方腾飞

在JDK7中,java.util.concurrent包含了一个相当便利的类,ThreadLocalRandom,当应用程序期望在多个线程或ForkJoinTasks中使用随机数时。

对于并发访问,使用TheadLocalRandom代替Math.random()可以减少竞争,从而获得更好的性能。
阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: Oracle官方并发教程之并发随机数


《Java 7并发编程实战手册》第六章并发集合

Snip20140120_1
人民邮电出版社出版的《Java 7并发编程实战手册》终于出版了,译者是俞黎敏和申绍勇,该书将于近期上架。之前并发编程网组织翻译过此书,由于邮电出版社在并发网联系他们之前就找到了译者,所以没有采用并发网的译稿,但邮电出版社将于并发网展开合作,发布该书的样章(样章由并发网挑选,你也可以回帖告诉我们你想看哪一章的样章),并组织赠书活动回馈给活跃读者。活动详情请时刻关注并发网的微博和微信(微信号:ifeves),最后祝各位用餐愉快!:)

阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 《Java 7并发编程实战手册》第六章并发集合


[Google Guava] 2.1-不可变集合

原文链接 译者:沈义扬

范例

public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of(
        "red",
        "orange",
        "yellow",
        "green",
        "blue",
        "purple");

class Foo {
    Set<Bar> bars;
    Foo(Set<Bar> bars) {
        this.bars = ImmutableSet.copyOf(bars); // defensive copy!
    }
}

为什么要使用不可变集合

不可变对象有很多优点,包括:

  • 当对象被不可信的库调用时,不可变形式是安全的;
  • 不可变对象被多个线程调用时,不存在竞态条件问题
  • 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
  • 不可变对象因为有固定不变,可以作为常量来安全使用。

创建对象的不可变拷贝是一项很好的防御性编程技巧。Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本。
阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: [Google Guava] 2.1-不可变集合


[Google Guava] 1.3-常见Object方法

原文链接 译者: 沈义扬

equals

当一个对象中的字段可以为null时,实现Object.equals方法会很痛苦,因为不得不分别对它们进行null检查。使用Objects.equal帮助你执行null敏感的equals判断,从而避免抛出NullPointerException。例如:

Objects.equal("a", "a"); // returns true
Objects.equal(null, "a"); // returns false
Objects.equal("a", null); // returns false
Objects.equal(null, null); // returns true

注意:JDK7引入的Objects类提供了一样的方法Objects.equals

阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: [Google Guava] 1.3-常见Object方法


Google-Guava Concurrent包里的Service框架浅析

原文地址  译文地址 译者:何一昕 校对:方腾飞

概述

Guava包里的Service接口用于封装一个服务对象的运行状态、包括start和stop等方法。例如web服务器,RPC服务器、计时器等可以实现这个接口。对此类服务的状态管理并不轻松、需要对服务的开启/关闭进行妥善管理、特别是在多线程环境下尤为复杂。Guava包提供了一些基础类帮助你管理复杂的状态转换逻辑和同步细节。

阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: Google-Guava Concurrent包里的Service框架浅析


为什么java.util.concurrent 包里没有并发的ArrayList实现?

原文链接 作者:Stephen C 译者:郑旭东  校对:方腾飞

问:JDK 5在java.util.concurrent里引入了ConcurrentHashMap,在需要支持高并发的场景,我们可以使用它代替HashMap。但是为什么没有ArrayList的并发实现呢?难道在多线程场景下我们只有Vector这一种线程安全的数组实现可以选择么?为什么在java.util.concurrent 没有一个类可以代替Vector呢?

答:我认为在java.util.concurrent包中没有加入并发的ArrayList实现的主要原因是:很难去开发一个通用并且没有并发瓶颈的线程安全的List。

阅读全文


AQS的原理浅析

本文是《Java特种兵》的样章,本书即将由工业出版社出版

AQS的全称为(AbstractQueuedSynchronizer),这个类也是在java.util.concurrent.locks下面。这个类似乎很不容易看懂,因为它仅仅是提供了一系列公共的方法,让子类来调用。那么要理解意思,就得从子类下手,反过来看才容易看懂。如下图所示:
QQ图片20140110194431

图 5-15 AQS的子类实现

阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: AQS的原理浅析


google Guava包的ListenableFuture解析

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

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

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

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

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: google Guava包的ListenableFuture解析


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

问题描述

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

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 您还有心跳吗?超时机制分析


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

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

用 FindBugs 分析并发代码

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

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

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 测试并发应用(六)用 FindBugs 分析并发代码


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

本文首发于InfoQ

1. 什么是Fork/Join框架

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

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


阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 聊聊并发(八)——Fork/Join框架介绍


ReentrantLock(重入锁)以及公平性

Dedicate to Molly.

简介

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

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: ReentrantLock(重入锁)以及公平性


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

原文首发于InfoQ

1. 什么是阻塞队列?

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

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 聊聊并发(七)——Java中的阻塞队列


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可能还没有进行写入操作呢,虽然代码顺序上写操作是在前面的。这就是可见性问题的由来。

阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: happens-before俗解


AbstractQueuedSynchronizer的介绍和原理分析

感谢同事【魏鹏】投递本稿。 Dedicate to Molly.

简介

提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架。该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础。使用的方法是继承,子类通过继承同步器并需要实现它的方法来管理其状态,管理的方式就是通过类似acquire和release的方式来操纵状态。然而多线程环境中对状态的操纵必须确保原子性,因此子类对于状态的把握,需要使用这个同步器提供的以下三个方法对状态进行操作:

  • java.util.concurrent.locks.AbstractQueuedSynchronizer.getState()
  • java.util.concurrent.locks.AbstractQueuedSynchronizer.setState(int)
  • java.util.concurrent.locks.AbstractQueuedSynchronizer.compareAndSetState(int, int)

子类推荐被定义为自定义同步装置的内部类,同步器自身没有实现任何同步接口,它仅仅是定义了若干acquire之类的方法来供使用。该同步器即可以作为排他模式也可以作为共享模式,当它被定义为一个排他模式时,其他线程对其的获取就被阻止,而共享模式对于多个线程获取都可以成功。

阅读全文

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: AbstractQueuedSynchronizer的介绍和原理分析


return top