`

并发专题 ---java.util.concurrent 包

 
阅读更多
java.util.concurrent 包

原子量、并发集合、同步器、可重入锁

在大型应用程序中,把线程管理和创建工作与应用程序的其余部分分离开更有意义。
线程池封装线程管理和创建线程对象。

可以使用 volatile 变量来以比同步更低的成本存储共享变量,但它们有局限性。虽然
可以保证其他变量可以立即看到对 volatile 变量的写入,但无法呈现原子操作的读-修改-写
顺序,这意味着 volatile 变量无法用来可靠地实现互斥(互斥锁定)或计数器。

使用锁synchronized 当线程被阻塞来等待锁时,它无法进行其他
任何操作。如果阻塞的线程是高优先级的任务,那么该方案可能造成非常不好的结果
使用锁synchronized 还有一些其他危险,如死锁(当以不一致的顺序获得多个锁时会发生死锁)。

CAS  有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B  放到这个位置;否则,不要更改该位置”
基于 CAS  的并发算法称为“无锁定算法”,因为线程不必再等待锁定。“无锁定算法”要求某个线程总是执行操作。
java.util.concurrent.atomic  包
中提供了原子变量的 9  种风格(AtomicInteger、AtomicLong、 AtomicReference、AtomicBoolean
原子整型、长型、 及原子标记引用和戳记引用类的数组形式,其原子地更新一对值)

大多数用户都不太可能自己使用原子变量开发无阻塞算法, 更可能使用
java.util.concurrent  中提供的版本,如 ConcurrentLinkedQueue。
-------------------------------------------------------------------------

同步器
=================
1 Semaphore
类 java.util.concurrent.Semaphore 提供了一个计数信号量,从概念上讲,信号量维护了一
个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release()
添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore
只对可用许可的号码进行计数,并采取相应的行动。

Semaphore  通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

2 CyclicBarrier
java.util.concurrent.CyclicBarrier 一个同步辅助类,它允许 (common barrier point)。
在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,
此时 CyclicBarrier  很有用。一组线程互相等待,直到到达某个公共屏障点。
因为该 barrier 在释放等待线程后可以重用,所以称它为循环的 barrier。

3 CountDownLatch
类 java.util.concurrent.CountDownLatch 是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,
它允许一个或多个线程一直等待。
用给定的数字作为计数器初始化 CountDownLatch。一个线程调用 await()方法后,在当前计数到达零之前,会一直受阻塞。
其他线程调用 countDown()  方法,会使计数器递减,所以,计数器的值为 0 后,会释放所有等待的线程。
其他后续的 await 调用都将立即返回。
这种现象只出现一次,因为计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。 

CountDownLatch  作为一个通用同步工具,有很多用途。使用“ 1 ”初始化的
CountDownLatch  用作一个简单的开/关锁存器,或入口:在通过调用 countDown()  的线程
打开入口前,所有调用  await  的线程都一直在入口处等待。用  N  初始化的 CountDownLatch 
可以使一个线程在 N  个线程完成某项操作之前一直等待,或者使其在某项操作完成 N  次之前一直等待。 

4 Exchanger
类 java.util.concurrent.Exchanger 提供了一个同步点,在这个同步点,一对线程可以交换
数据。每个线程通过 exchange()方法的入口提供数据给他的伙伴线程,并接收他的伙伴线程
提供的数据,并返回。

线程间可以用 Exchanger 来交换数据。当两个线程通过 Exchanger 交互了对象,这个交换对于两个线程来说都是安全的。

5 Future 和 FutureTask
接口 public interface Future<V> 表示异步计算的结果。它提供了检查计算是否完成的方法,
以等待计算的完成,并调用get()获取计算的结果。
FutureTask 类是   Future  的一个实现, 并实现了Runnable ,所以可通过 Executor(线程池)  来执行。
也可传递给Thread对象执行。

如果在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给
Future 对象在后台完成,当主线程将来需要时,就可以通过 Future 对象获得后台作业的计算结果或者执行状态。
FutureTask ft= new FutureTask(new Callable<V>() {
  @Override
  public V call() throws Exception {
   return null;
  }
       
  });
       
  new Thread(ft);

=====================================

显示锁
========
1 ReentrantLock
什么时候才应该使用 ReentrantLock  呢?
答案非常简单  ——  在确实需要一些 synchronized  所没有的特性的时候,比如时间锁等候、可中断锁等候、无块结构锁、
多个条件变量或者锁投票。

ReentrantLock 还有两个比较重要的方法是:tryLock()和 tryLock(long timeout, TimeUnit unit) 。
tryLock()仅在调用时锁未被另一个线程保持的情况下,才获取该锁。
后者如果锁在给定等待时间内没有被另一个线程持有,且当前线程未被中断,则获取该锁。

2 ReentrantReadWriteLock

ReadWriteLock  维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要
没有 writer,读取锁可以由多个 reader  线程同时保持。写入锁是独占的。

与互斥锁相比,读-写锁允许对共享数据进行更高级别的并发访问。虽然一次只有一个线程(writer  线程)可以修改共享数据,
但在许多情况下,任何数量的线程可以同时读取共享数据(reader  线程),读-写锁利用了这一点。
从理论上讲,与互斥锁相比,使用读-写锁所允许的并发性增强将带来更大的性能提高。

在实践中,只有在多处理器上并且只在访问模式适用于共享数据时,才能完全实现并发性增强。

与互斥锁相比,使用读-写锁能否提升性能则取决于读写操作期间读取数据相对于修改
数据的频率,以及数据的争用——即在同一时间试图对该数据执行读取或写入操作的线程数。

=========================

Fork-Join 框架
--
1 应用 Fork-Join

在 JDK 7 中,java.util.concurrent  包的新增功能之一是一个 fork-join  风格的并行分解框
架。fork-join  概念提供了一种分解多个算法的自然机制,可以有效地应用硬件并行性。
并行分解方法常常称作 fork-join,因为执行一个任务将首先分解(fork)为多个子任务,然后再合并(join)(完成
后)。

fork-join  框架通过一种称作工作窃取(work stealing)  的技术减少了工作队列的争用情
况。每个工作线程都有自己的工作队列,这是使用双端队列(或者叫做 deque)来实现的(Java 6  在类库中添加了几种 deque  实现,包括 ArrayDeque  和 LinkedBlockingDeque)。当一个任务划分一个新线程时,它将自己推到 deque  的头部。当一个任务执行与另一个未完成任务的合并操作时,它会将另一个任务推到队列头部并执行,而不会休眠以等待另一任务完成
(像 Thread.join()  的操作一样)。当线程的任务队列为空,它将尝试从另一个线程的 deque 的尾部  窃取另一个任务。


fork-join  方法提供了一种表示可并行化算法的简单方式,而不用提前了解目标系统将提供多大程度的并行性。
所有的排序、搜索和数字算法都可以进行并行分解(以后,像 Arrays.sort()  这样的标准库机制将会使用 fork-join  框架,
允许应用程序免费享有并行分解的益处)。随着处理器数量的增长,我们将需要在程序内部使用更多的并行性,以有效利用
这些处理器;对计算密集型操作(比如排序)进行并行分解,使程序能够更容易利用未来的硬件。

2 应用 ParallelArray

在主流服务器应用程序中,最适合更细粒度并行性的地方是数据集的排序、搜索、选择和汇总。
其中的每个问题都可以用 divide-and-conquer(拆分-合并)  轻松地并行化,并能轻松地表示为
fork-join  任务。
例如,要将对大数据集求平均值的操作并行化,可以递归地将大数据集分解成更小的数据集 
—  就像在合并排序中做的那样  —  对子集求均值子集的平均值的加权平均值。


对于排序和搜索问题,fork-join  库提供了一种表示可以并行化的数据集操作的非常简单的途径:ParallelArray  类。
其思路是:
用 ParallelArray  表示一组结构上类似的数据项,用 ParallelArray  上的方法创建一个对分解数据的具体方法的描述。
然后用该描述并行地执行数组操作(幕后使用的是 fork-join  框架)。这种方法支持声明性地指定数据选择、转换和处理操作,
允许框架计算出合理的并行执行计划,就像数据库系统允许用 SQL  指定数据操作并隐藏操作的实现机制一样。
ParallelArray  的一些实现可用于不同的数据类型和大小,包括对象数组和各种原语组成的数组。

随着可用的处理器数量增加,我们需要发现程序中更细粒度的并行性来源。最有吸引力
候选方案之一是聚合数据操作——排序、搜索和汇总。JDK 7  中将引入的 fork-join  库提供
了一种  “轻松表示”  某类可并行化算法的途径,从而让程序能够在一些硬件平台上有效运
行。通过声明性地描述想要执行的操作,然后让 ParallelArray  确定具体的执行方法,fork-join 库的
ParallelArray  组件使并行聚合操作的表示变得更加简单。
分享到:
评论

相关推荐

    java并发工具包 java.util.concurrent中文版用户指南pdf

    1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    Tomcat内存溢出的解决方法(java.util.concurrent.ExecutionException)

    "java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError" 是一个典型的错误提示,它表明在并发执行过程中遇到了内存不足的问题。下面我们将深入探讨这个问题的原因、影响以及如何解决。 内存溢出...

    atlassian-util-concurrent-0.0.12.jar.zip

    本文将详细探讨Atlassian发布的`atlassian-util-concurrent-0.0.12.jar`库,这是一个专门针对并发处理的工具集,旨在简化Java开发中的多线程操作。 `atlassian-util-concurrent-0.0.12.jar.zip`是这个库的压缩文件...

    Java并发工具包java.util.concurrent用户指南中英文对照阅读版.pdf

    java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    java并发工具包 java.util.concurrent中文版pdf

    ### Java并发工具包 `java.util.concurrent` 知识点详解 #### 一、引言 随着多核处理器的普及和应用程序复杂度的增加,多线程编程成为了现代软件开发不可或缺的一部分。为了简化并发编程的复杂性,Java 5 引入了 `...

    backport-util-concurrent(2.2 /3.1)

    backport-util-concurrent项目最初由Doug Lea创建,他是Java并发领域的权威人物,他的贡献包括`java.util.concurrent`包的实现。这个库的核心目标是为那些无法升级到Java 5或更高版本的系统提供线程安全和并发控制的...

    java.util.concurrent 学习ppt

    Java.util.concurrent是Java 5.0引入的一个重要包,它为多线程编程提供了一组高级并发工具。这个包的设计者是Doug Lea,它的出现是JSR-166的一部分,也被称作Tiger更新。Java.util.concurrent的引入是为了解决传统...

    java.util.concurrent

    java.util.concurrent总体概览图。 收取资源分3分。需要的同学可以下载一下。 java.util.concurrent主要包括5个部分executor,colletions,locks,atomic,tools。 该图详细的列举了并发包下面的结构,包含所有接口和...

    java.util.concurrent系列文章(1)

    Java 5 引入了 `java.util.concurrent` 包,该包提供了丰富的 API 来简化并发编程任务。本篇文章将深入探讨 `java.util.concurrent` 包中的一些核心概念和技术,特别是 `ConcurrentHashMap` 和 `...

    动画学习 java.util.concurrent并发工具包

    如何启动:以win7系统为例,最好jdk8 1.打开cmd,cd到jdk的path,本机是:cd C:\Java\jdk6\bin ...java -cp D:\javaConcurrentAnimated.jar vgrazi.concurrent.samples.launcher.ConcurrentExampleLauncher

    Java并发工具包java.util.concurrent用户指南中英文对照阅读版

    1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    The java.util.concurrent Synchronizer Framework

    为了更好地支持并发编程,Java平台在J2SE 1.5版本中引入了`java.util.concurrent`包,这是一个包含了许多中级并发支持类的集合,通过Java社区过程(Java Community Process, JCP)的Java规范请求(Java ...

    java.util.concurrent-多线程框架.docx

    在 java.util.concurrent 多线程框架中,还提供了多种其他机制,包括并发集合、同步器、lock 等,以便开发者更方便地编写高效、可靠的多线程程序。并发集合提供了多种机制,包括 CopyOnWriteArrayList、...

    java并发工具包 java.util.concurrent中文版-带书签版

    Java并发工具包(java.util.concurrent)是Java平台上用于高效、安全地处理多线程编程的重要组件。这个包包含了丰富的并发工具类,旨在帮助开发者构建高度并发的程序,提高程序的性能和可伸缩性。本资源是该工具包的...

    java.util.concurrent.uml.pdf

    标题中提到了“java.util.concurrent.uml.pdf”,这表明文件是一份Java并发编程工具包java.util.concurrent的UML(统一建模语言)类结构图的PDF格式文件。UML图能够帮助开发者理解Java并发包中的类、接口及其关系,...

    backport-util-concurrent-3.1.jar和geronimo-stax-api_1.0_spec-1.0.1.jar

    "backport-util-concurrent-3.1.jar"是Java.util.concurrent包的回移植版本,主要用于Java 5之前的JRE环境。它提供了与Java 5及更高版本相同的并发工具类,如线程池、Future、CyclicBarrier等。这些工具可以提高多...

    Java高性能线程库(java.util.concurrent包的补充)

    一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用。该类库不提供远程的消息功能,其设计的宗旨是实现一个内存中的消息传递机制. 主要特点有: * All ...

Global site tag (gtag.js) - Google Analytics