java并发包源码剖析 - 序章

    为了更好地理解并发,因此决定对java的整个并发包进行源码程度剖析。

    首先介绍一下整个并发包的大体情况。主要分为三个包
    1.java.util.concurrent  包括一些规范化可扩展的框架,即Executors,Queues,Synchronizers,Concurrent Collections等
    2.java.util.concurrent.atomic  扩展了volatile变量,成员域,和数组元素的概念,同时也提供了原子条件更新操作(compareAndSet)

    3.java.util.concurrent.locks  提供了和内置的同步和监视器有区别的锁和条件等待的接口和类的框架。

    这三个包都主要提供了一些在并发编程中常用的多用途类。本次先从java.util.concurrent.locks包开始,逐步剖析整个并发包的框架代码。

java.util.concurrent.locks简介

    提供了和内置的同步和监视器有区别的锁和条件等待的接口和类框架。框架以更加繁琐的语法为代价,允许更加锁和条件状态的更加灵活性的运用。

    Lock接口支持不同语义(可重入,公平等)的锁的原则,可以在非阻塞式结构的上下文(包括 hand-over-hand 和锁重排算法)中使用这些规则。主要的实现是 ReentrantLock 。

    ReadWriteLock接口类似地定义了可以被读时共享,写时独占的锁。只提供了一个实现,ReentrantReadWriteLock,因此它已经代表了大部分常规的用途。但是程序员可以根据需求创建自己的实现。

    Condition接口描述了可以与锁关联的条件变量。这些在用法与隐式监视器Object.wait很想死,但是提供了扩展性。举例来说,不同的条件对象可以与单个锁关联。

    AbstractQueuedSynchronizer类为定义锁和其它依赖于队列阻塞线程的同步器的一个有用的基类。AbstractQueuedLongSynchronizer提供类相同的用途,但是扩展支持到64位同步器状态。同样作为扩展类,AbstractOwnableSynchronizer,是一个帮助记录获取独占同步器线程的类。LockSupport类提供类更加底层的有助于开发者实现自己定制锁类的阻塞和非阻塞。

java.util.concurrent简介

    juc包主要提供了并发编程中用途广泛的类。juc包含类一些规格化可扩展的框架,同时包括一些需要繁琐或者复杂实现的类。


Executors
    接口Executor是一个简单的规范化定义了可定制的线程子系统,即线程池,异步I/O,还有轻量级任务框架。基于使用的具体Executor类,任务可能会执行在一个新建的线程,或者一个已经存在的专门执行任务的线程,又或者线程执行execute方法,另外还可能会顺序地或者并发地执行任务。ExecutorService提供了一个更加完整的异步任务执行框架。一个ExecutorService管理任务进队和任务调度,并且允许控制停止。ScheduledExecutorService实现了接口以提供延迟和周期性任务执行的支持。ExecutorServices提供方法去分类参数为Callable的异步执行函数,还有包含结果的Runnable类似物。Future返回函数的结果,允许决定执行是否完成,并且提供一种办法去取消执行。RunnableFuture是一个执行run方法并且在执行完成之后,设置执行结果的Future。
    实现。类ThreadPoolExecutor和ScheduledThreadPoolExecutor提供可调控,灵活的线程池。Executors类为大多数一般类型和设置的Executors提供工厂方法,同时也有一些多功效的方法去使用它们。其它基于Executors的实用类,包括具体的FutureTask类,提供了通用可扩展的Futures实现,还有ExecutorCompletionService类,协助负责协调一组异步任务的执行。

Queues
    ConcurrentlinkedQueue类提供了高效率可扩展的线程安全非阻塞FIFO队列。在juc包中的五个实现提供了BlockingQueue接口的扩展,该接口定义了put和take的阻塞版本,它们分别是:LinkedBlockingQueue,ArrayBlockingQueue,SynchronousQueue,PriorityBlockingQueue,和DelayQueue。这些不同的类包含了大部分诸如生产者-消费者,消息,并行任务,还有相关的同步设计等的通用使用上下文。

Timing
    TimeUnit类提供了多种的粒度(包括纳秒)去指定和控制基于超时的操作。大部分在包中的类包括类基于从超时到无穷等待的操作。所有这些例子中,当使用了超时之后,超时指定了方法在假设它超时前的最小等待时间。实现里尽了“最大努力”在当超时发生时,最快时刻的检测。所有方法接受超时参数的都把小于或等于零的值意味着不需要等待。要无限等待,你可以用Long.MAX_VALUE值。

Synchronizers
    四个类辅助特殊用途的同步惯用语法。
    Semaphore是经典的并发工具。
    CountDownLatch是一个非常简单同时也是非常通用的阻塞直至指定数量的信号,事件,或者状态获取的工具。
    CyclicBarrier是一个可以重置的多路同步点,在某些并发编程风格中有用。
    Exchanger允许两条线程在相遇点交换对象,在某些管道设计中很有用。

Concurrent Collections
    除了队列,本包提供了在多线程上下文中设计实现的集合:ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet, CopyOnWriteArrayList, 还有CopyOnWriteArraySet。当多线程访问一个集合时,ConcurrentHashMap通常比synchronized的HashMap更好,ConcurrentSkipListMap通常比synchronized的TreeMap更好,CopyOnWriteArrayList在预期内读和遍历次数大大超过列表更新的次数时,通常比synchronized的ArrayList更好。
    在本包内的某些类的名字前缀“Concurrent”是一种速记,表明了与类似的“synchronized”类的不同之处。例如,java.util.Hashtable和Collections.synchronizedMap(new HashMap())是同步的(synchronized)。但是ConcurrentHashMap是并发的(“concurrent”)。一个并发的集合是线程安全的,但是不是被一个单独的独占锁管理。对于ConcurrentHashMap来说,它安全地允许了任何数量的并发读操作,同时和一个可调度数量的并发写操作。“Synchronized”类在当你在需要通过一个单独的锁来避免所有并发访问时会很有用,这是以更差的可伸缩性为代价的前提下。在其它情况下,多线程期望访问一个通常的集合时,“并发”版本通常会更加好。当集合是非共享的,或者只被获取了其它锁才可以访问的条件下,非同步的集合一般更加好。
    大部分并发集合的实现(包括大部分Queues)都提供了弱连续(weak consistent)的迭代,这是与通常的java.util规定的fast-fail迭代遍历中不同的地方。一个弱连续的迭代是线程安全的,但是在迭代过程中不必要的冻结(freeze)了集合,所以它可能(也可能不会)反应从迭代器创建以来的更新。

Memory Consistency Properties
    JLS第17章里定义了happens-before在内存读写共享变量操作的关系。只当在写操作happens-before读操作的时候,单条线程写的结果是保证被另外一条读操作的线程可见的。Synchronized和volatile关键字,另外还有Thread.start()和Thread.join()方法,可以组成happens-before关系。特别地:
    1、线程内每个动作对于稍后的程序顺序中的每个动作可见。
    2、对一个监视器的解锁happens-before于每一个后续对同一个监视器的加锁。
    3、对volatile字段的写入操作happens-before于每一个后续的同一个字段的读操作。不过volatile不提供独占锁互斥性。
    4、Thread.start()的调用会happens-before于启动线程里面的动作。
    5、Thread中的所有动作都happens-before于其他从Thread.join()中返回的线程。
    在juc包中所有的类和它的子包都扩展这些保证到更高层次的同步性。特别地:
    1、在添加对象进去任意的并发集合中之前的动作都对其它线程后续的访问或元素从集合删除的可见。
    2、在Runnable递交给Executor之前在线程的所有动作都对执行开始的动作可见。类似地,Callables递交给ExecutorService也使用。
    3、Future的异步计算动作对后续其它线程Future.get()方法调用可见。
    4、在“释放”同步器方法,如Lock.unlock,Semaphore.release,还有CountDownLatch.countDown之前的动作对后续的在其它线程里于相同的同步器的“获取”方法,如Lock.lock,Semaphore.acquire,Condition.await,和CountDownLatch.await可见。
    5、对每对通过Exchanger成功交往对象的线程来说,在每条调用exchange()方法之前的动作都对另外一条线程的后续的当前exchange()方法可见。
    6、在CyclicBarrier.await调用之前的动作,对于后续栅栏动作的执行可见,并且在栅栏动作的执行对于后续另外线程的成功调用await方法可见。

    其中A表示抽象类(Abstract class),I表示接口(Interface)得出以下部分:

Executors
AbstractExecutorService(A)
Callable(I)
CompletionService(A)
Executor(I)
ExecutorCompletionService
Executors
ExecutorService(I)
ForkJoinPool
ForkJoinTask(I)
ForkJoinWorkerThread
Future(I)
FutureTask
RecursiveAction(A)
RecursiveTask(A)
RejectedExecutionHandler(A)
RunnableFuture(I)
RunnableScheduledFuture(I)
ScheduledExecutorService
ScheduledFuture(I)
ScheduledThreadPoolExecutor
ThreadFactory(I)
ThreadLocalRandom
ThreadPoolExecutor

Timing
TimeUnit

Queues
ArrayBlockingQueue
BlockingQueue(I)
ConcurrentLinkedQueue
Delayed(I)
DelayQueue
LinkedBlockingQueue
LinkedTransferQueue
PriorityBlockingQueue
SynchronousQueue
TransferQueue(I)

Deque
BlockingDeque(I)
ConcurrentLinkedDeque
LinkedBlockingDeque

Synchronizers
CountDownLatch
CyclicBarrier
Exchanger
Phaser
Semaphore

Concurrent Collections
ConcurrentHashMap
ConcurrentMap(I)
ConcurrentNavigableMap(I)
ConcurrentSkipListMap
ConcurrentSkipListSet
CopyOnWriteArrayList
CopyOnWriteArraySet

你可能感兴趣的:(Java)