AirJD 焦点
AirJD

没有录音文件
00:00/00:00
加收藏

Java 并发编程培训(阿里巴巴)

发布者 javalover
发布于 1427880104826  浏览 6770 关键词 Java 
分享到

第1页

Java 并发编程
龙浩

第2页

在一个list中有过亿条的Integer类型的值,如何更快的计算这些值的总和?

一个计算的问题
简单的方法:更快的CPU来遍历
靠谱的方法:分而治之来处理
进一步的方法:Fork/jion

第3页


简单的方法靠谱么?
免费午餐已经结束——软件历史性地向并发靠拢
http://news.csdn.net/n/20071219/111880.html
软层次上:遍历是不靠谱的,for小学生了!
图1:为什么没有10GHz的芯片呢?受制于一些物理学问题,如散热(发热量太大且难以驱散)、功耗(太高)以及泄漏问题。
     参考:NetBurst的继承者 Core微处理器架构技术解析http://diy.yesky.com/cpu/389/2340389.shtml?3093
图2:在IDF05(Intel Developer Forum 2005)上。Intel首席执行官Craig Barrett就取消4GHz芯片计划一事,半开玩笑当众单膝下跪致歉。

第4页

靠谱的方法简单么?(分而治之)
list1
list2
list3
Concurrency
那帮Java大神在他们书中说:
在对性能的追求很可能是并发bug唯一最大的来源!
So:
同样不是免费的午餐,需要学习和批量实践。

第5页

目录
 线程
 并发编程(juc)
 线程监控工具
编程思想和实践
 Fork/Jion框架

第6页

Visibility:通过并发线程修改变量值, 必须将线程变量同步回主存后, 其他线程才能访问到。
Ordering:通过java提供的同步机制或volatile关键字, 来保证内存的访问顺序。
Cache coherency :它是一种管理多处理器系统的高速缓存区结构,其可以保证数据在高速缓存区到内存的传输中不会丢失或重复。 
Happens-before ordering:synchronized,volatile,final,java.util.concurrent.lock|atomic

线程:先让路给内存模型
这里有详述:http://is.gd/c8fhE (别迷恋哥,哥只是传说!)
别迷信内存模型的架构,传说SUN的那帮专家都有时候被专家搞迷糊了。

第7页

内存中的可见部分
所有内存都是共享的么?
No, only globals and heap.
In Java, classes are global and static variables declared inside classes are global too. All the rest is local.
All variables declared inside a method are locals, therefore they are not shared.
The heap memory is never a problem even though it is shared, because variables pointing to them are either global or local.

第8页

线程:synchronized
保证原子性和可见性
public synchronized static int getAge(int i){
return i;
}
public synchronized String name(){
return "longhao";
}
public void modifyHeight(){
synchronized(this){
//do something
}
//do something
}

第9页

线程:Java Monitors
This figure shows the monitor as three rectangles. In the center, a large rectangle contains a single thread, the monitor's owner. On the left, a small rectangle contains the entry set. On the right, another small rectangle contains the wait set. Active threads are shown as dark gray circles. Suspended threads are shown as light gray circles. 
中文翻译为管程。synchronized、Object.wait()、Object.notify()的底层实现。但是java原生提供的monitor不完整,因为没有提供Condition,Object本身隐含提供一Condition。
http://www.artima.com/insidejvm/ed2/threadsynch.html

第10页

线程:独占锁(synchronized)
非方法修饰符,注意方法覆写的时候需要加上synchronized;
经典的顺序锁问题(两个线程安全的方法放在一起线程安全么? )
getClass的问题。
……
这里详细介绍:http://www.ibm.com/developerworks/cn/java/j-lo-lock/
不过瘾的看这个:http://book.csdn.net/bookfiles/398/10039814664.shtml

第11页

分拆前:思考问题,顺便教你一招!
分拆不了人,工具还不能分拆么?对,买3个手机去……

第12页

线程:分拆锁

第13页

线程:分离锁
分离锁负面作用:对容器加锁,进行独占访问更加困难,并且更加昂贵了。
内存使用的问题:sina就曾经因为在Action层使用ConcurrentHashMap而导致内存使用过大,修改array后竟然单台服务器节省2G。
这里详细介绍:http://www.ibm.com/developerworks/cn/java/j-lo-lock/
不过瘾的看这个:http://book.csdn.net/bookfiles/398/10039814664.shtml

第14页

线程:static的案例
public class StaticThreadTest {
//线程避免调用这个;
public static Tree tree = new Tree(“jizi”,“2”);
public static void createTree(Tree trees){
    Tree t = tree;                   if(trees.getName().equals("pg")){t.setName("ceshi");}}
public static void main(String[] args) throws InterruptedException{
ExecutorService exec =     Executors.newFixedThreadPool(10);for(int i=0;i<10;i++){  exec.execute(new TreeThread(i));Thread.sleep(50);
}
exec.shutdown();
exec.awaitTermination(1, TimeUnit.SECONDS);
}
}

第15页


线程:可见性
volatile关键字:
1:简化实现或者同步策略验证的时候来使用它;
2:确保引用对象的可见性;
3:标示重要的生命周期的事件,例如:开始或者关闭。

脆弱的volatile的使用条件:
1:写入变量不依赖变量的当前值,或者能够保证只有单一的线程修改变量的值;
2:变量不需要和其他变量共同参与不变约束;
3:访问变量时不需要其他原因需要加锁。
private volatile boolean isInterrupted = false;
注意:wait,sleep,yield,join可都是native的,抛出InterruptedException。

第16页


任务的取消和线程超时

第17页


线程中断
注意:wait,sleep,yield,join都是native的,抛出InterruptedException。

第18页

教父Joshua Bloch说线程:
对共享可变数据同步访问;
避免过多的同步;
永远不要在循环外面调用wait;
不要依赖于线程调度器;
线程安全的文档化;
避免使用线程组。

第19页

目录
 线程
 并发编程(juc)
 线程监控工具
编程思想和实践
 Fork/Jion框架

第20页


开始并发编程了

第21页

行动之前,拜神先
Mr. concurrency ,当今世界上并发程序设计领域的先驱,著名学者。他是util.concurrent包的作者,JSR166规范的制定。
图书著作《Concurrent Programming in Java: Design Principles and Patterns》。
其” A Scalable Elimination-based Exchange Channel”和”Scalable Synchronous Queues”两篇论文列为非阻塞同步算法的经典文章。
A  fork/jion framework同样影响着java7。
Doug Lea

第22页

Amdahl定律


并发编程:三大定律(1)
讨论的是加速比(speedup)的问题
10个老婆一个月也不能把儿子生出来。

第23页

Gustafson 定律


并发编程:三大定律(2)
Gustafson假设随着处理器个数的增加,并行与串行的计算总量也是可以增加的。Gustafson定律认为加速系数几乎跟处理器个数成正比,如果现实情况符合Gustafson定律的假设前提的话,那么软件的性能将可以随着处理个数的增加而增加。
如何更快的生10个孩子的问题。

第24页

Sun-Ni定律

并发编程:三大定律(3)
充分利用存储空间等计算资源,尽量增大问题规模以产生更好/更精确的解。
在Gustafson定理中,加速比与处理器数几乎呈线性关系,这是Sun-Ni定理中G(p)=p的情况;而如果G(p)=1,则是表明工作量无增加,即Amdahl定理中的情况。

第25页


总结不是API,是寂寞!

第26页


来个高清无码版
Executors
Executor
ExecutorService
ScheduledExecutorService
Callable
Future
ScheduledFuture
Delayed
CompletionService
ThreadPoolExecutor
ScheduledThreadPoolExecutor
AbstractExecutorService
Executors
FutureTask
ExecutorCompletionService
Queues
BlockingQueue
ConcurrentLinkedQueue
LinkedBlockingQueue
ArrayBlockingQueue
SynchronousQueue
PriorityBlockingQueue
DelayQueue
Concurrent Collections
ConcurrentMap
ConcurrentHashMap
CopyOnWriteArray{List,Set}

Synchronizers
CountDownLatch
Semaphore
Exchanger
CyclicBarrier

Timing
TimeUnit
Locks
Lock
Condition
ReadWriteLock
AbstractQueuedSynchronizer
LockSupport
ReentrantLock
ReentrantReadWriteLock
Atomics
Atomic[Type], Atomic[Type]Array
Atomic[Type]FieldUpdater
Atomic{Markable,Stampable}Reference

第27页


ThreadPoolExecutor:自己动手,丰衣足食!
 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue());
    }
1:线程池的大小最好是设定好,因为JDK的管理内存毕竟是有限的;
2:使用结束,需要关闭线程池;
3: Runtime.getRuntime().addShutdownHook(hook); 对不能正常关闭的
线程做好相关的记录。

第28页


Executors:ExecutorService
严重注意:别设置线程池无限大小

第29页


入门版:CompletionService
生产者消费者模式的简要实现版本。

第30页


双剑合璧:Future+Callable

第31页


任务池: ScheduledExecutorService
计划任务执行相关的操作,使用java真幸福,选择多多!
存在一种算法TimerWheel,适用于大规模的定时器实现。这个算法最早是被设计用来实现 BSD 内核中定时器的,后来被广泛移植到诸如 ACE 等框架中,堪称 BSD 中经典算法之一,能针对定时器的各类常见操作提供接近常数时间的响应,且能根据需要很容易进行扩展。(TimerWheel在Java 5中实现很简单)

第32页


阻塞队列:BlockingQueue
Kaopuability:插入(offer);移除(poll)

第33页


BlockingQueue 的诸侯领地
ArrayBlockingQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。
Delayed 元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素.
LinkedBlockingDeque一个基于已链接节点的、任选范围的阻塞双端队列。 
LinkedBlockingQueue一个基于已链接节点的、范围任意的 blocking queue。此队列按 FIFO(先进先出)排序元素
PriorityBlockingQueue一个无界阻塞队列,它使用与类 PriorityQueue 相同的顺序规则,并且提供了阻塞获取操作。
SynchronousQueue一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然。

第34页


BlockingDeque:双端队列

第35页


并发集合:你值得拥有

第36页


ConcurrentHashMap:解放军38军
你那飘逸的同步,分离锁的设计,再hash算法以及游离于多个Segment的耍心跳的各种操作,都深深的吸引了我。
详细设计细节:http://www.ibm.com/developerworks/java/library/j-jtp08223/

第37页


比较Map的性能

第38页


CopyOnWriteArray{List,Set}
当读操作远远大于写操作的时候,考虑用这个并发集合。例如:维护监听器的集合。注意:其频繁写的效率可能低的惊人。
奇技淫巧:屏蔽add带来的数组拷贝;
public List array = new ArrayList();
public List list = new CopyOnWriteArrayList(array);

第39页


同步器:四大金刚

第40页


闭锁:CountDownLatch
等待启动信号
等待完成信号
继续
启动信号+完成信号的模式
N部分锁存器倒计数模式;
当线程必须用这种方法反复倒计数时,可改为使用 CyclicBarrier
典型应用:手动控制事务,从数据库读取多份数据做初始化;

第41页


关卡:CyclicBarrier
Barrier
A
B
C
Barrier
Barrier
A
B
C
A barrier: A barrier is a coordination mechanosm (an algorithm) that forces process which participate in a concurrent (or distributed) algorithm to wait until each one of them has reached a certain point in its program. The collection of these coordination points is called the barrier. Once all the processes have reached the barrier, they are all permitted to continue past the barrier. 

第42页


信号量:Semaphore
获取信号( acquire();)

第43页


交换器:Exchanger
数据分解和数据流分解的一种技巧,可被视为 SynchronousQueue 的双向形式。
JDK5时支持2个线程之间交换数据,JDK6后支持多个。
至今我没有用过

第44页


锁云:你的柔情我永远不懂
内部锁
互斥锁
分离锁
分拆锁
闭锁
独占锁
读写锁
顺序锁

第45页


互斥锁: ReentrantLock
Lock 更加灵活,性能更好interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException;
void unlock();
Condition newCondition();
}
支持多个Condition
可以不以代码块的方式上锁
可以使用tryLock,并指定等待上锁的超时时间
调试时可以看到内部的owner thread,方便排除死锁
RenntrantLock支持fair和unfair两种模式

第46页


互斥锁(公平与非公平)和内部锁性能对比图
结论:非公平互斥锁和内部锁性能在jdk6_17下性能基本一样。
测试机:酷睿2.66双核,2G内存,win7
循环数/线程数

第47页


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

第48页


高深:AbstractQueuedSynchronizer
为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量、事件,等等)提供一个框架;
基于JDK底层来操控线程调度,LockSupport.park和LockSupport.unpark;
此类支持默认的独占 模式和共享 模式之一,或者二者都支持;
如果想玩玩它,请看CountDownLatch的源码。
当然,也可以去FutureTask这个类看看。

第49页

目录
 线程
 并发编程(juc)
 线程监控工具
编程思想和实践
 Fork/Jion框架

第50页


Fork/Join Framework (1)
Work Stealing

第51页


Fork/Join Framework
FJTask框架是Cilk用到的设计方案的变体,相关系统依赖于轻量级可执行任务。这些框架都是像操作系统映射线程到CPU一样来映射任务到线程,从而开发单纯,有规律,有约束力的fork/join程序来执行映射动作。
工作线程池是确定的,每个工作线程(Thread子类FJTaskRunner的一个实例)是处理队列中任务的标准线程。正常的,工作线程的数量和系统的CPU的数量是一致的。任何合乎情理的映射策略将把这些线程映射到不同的cpu。
所有的fork/join任务都是一个轻量级可执行类的实例,不是一个线程实例。在java中,独立的可执行任务必须实现Runnable接口并定义一个run()方法。在FJTask框架中,这些任务是FJTask的子类而不是Thread的子类,它们都实现了Runnable接口
一个简单的控制和管理设施(这里讲的是FJTaskRunnerGroup)设置工作池,从一个正常的线程(例如java语言中的main()方法)调用启动执行提供的fork/join任务。
Doug Lea论文:http://gee.cs.oswego.edu/dl/papers/fj.pdf

第52页


Fork/Join 的案例:求数组中的最大值

第53页


Fork/Join 运行测试结果
表 1. 在不同系统上从 500k 个元素的数组中运行 select-max 的结果
fork-join 池中的线程数量与可用的硬件线程(内核数乘以每个内核中的线程数)相等

第54页


Fork/Join 有用的资源
表 1. 在不同系统上从 500k 个元素的数组中运行 select-max 的结果
jsr166:
http://gee.cs.oswego.edu/dl/concurrency-interest/index.html

Java 理论与实践:应用 fork-join 框架:Brian Goetz
http://www.ibm.com/developerworks/cn/java/j-jtp11137.html
http://www.ibm.com/developerworks/cn/java/j-jtp03048.html

JDK 7 中的 Fork/Join 模式
http://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/index.html

第55页

目录
 线程
 并发编程(juc)
 线程监控工具
编程思想和实践
 Fork/Jion框架

第56页


线程监控:DIY
Windows 下面DIY方式很多,txt编辑器都是好东西

第57页


线程监控:Jconsole

第58页


线程监控:VisualVm本地
下载地址:https://visualvm.dev.java.net/download.html
JDK1.6之后自带了这个攻击,在java_home/bin下面;
喜新厌旧的GGDDJJMM去上述地址下载吧!

第59页


内存监控:VisualVm远程

第60页


Thread Dump Analyzer
https://tda.dev.java.net/

第61页

目录
 线程
 并发编程(juc)
 线程监控工具
 编程思想和实践
 Fork/Jion框架

第62页


基本思想:CAS操作
处理器指令,全称Compare and swap,原子化的读-该-写指令
处理竞争策略:单个线程胜出,其他线程失败,但不会挂起
目前的多处理器系统基本都支持原子指令,典型模式:首先从V中读取值B,由A生成新值B,然后使用CAS原子化地把V的值由A修改成B,并且期间不能有其他线程修改V的值,CAS能够发现来自其他线程的干扰,所以即使不使用锁,也能解决原子化地读-写-改的问题

第63页


基本思想:Atomic原子类
基于硬件CAS实现Atomic类
分四组:计量器、域更新器、数组、复合变量
更佳的volatile
目标1:实现复杂算术运算:incrementAndGet、getAndIncrement等
目标2:支持Java类型对象的CAS操作:compareAndSet
为了解决ABA问题,提供了AtomicStampedReference(同系AtomicMarkableReference),实现原子化的条件更新,允许“版本化”引用,更新时,同时更新应用和版本号。参考代码Atomic. incrementAndGet :
AtomicReference:
private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
      try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicReference.class.getDeclaredField("value"));
      } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile V value;

    /**
     * Creates a new AtomicReference with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicReference(V initialValue) {
        value = initialValue;
    }

    /**
     * Creates a new AtomicReference with null initial value.
     */
    public AtomicReference() {
    }

    /**
     * Gets the current value.
     *
     * @return the current value
     */
    public final V get() {
        return value;
    }

    /**
     * Sets to the given value.
     *
     * @param newValue the new value
     */
    public final void set(V newValue) {
        value = newValue;
    }

    /**
     * Eventually sets to the given value.
     *
     * @param newValue the new value
     * @since 1.6
     */
    public final void lazySet(V newValue) {
        unsafe.putOrderedObject(this, valueOffset, newValue);
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     * @param expect the expected value
     * @param update the new value
     * @return true if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(V expect, V update) {
        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * 

May fail spuriously
     * and does not provide ordering guarantees, so is only rarely an
     * appropriate alternative to {@code compareAndSet}.
     *
     * @param expect the expected value
     * @param update the new value
     * @return true if successful.
     */
    public final boolean weakCompareAndSet(V expect, V update) {
        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
    }

    /**
     * Atomically sets to the given value and returns the old value.
     *
     * @param newValue the new value
     * @return the previous value
     */
    public final V getAndSet(V newValue) {
        while (true) {
            V x = get();
            if (compareAndSet(x, newValue))
                return x;
        }
    }

第64页


基本思想:非阻塞算法
一个线程的失败或挂起不影响其他线程
J.U.C的非阻塞算法依赖Atomic
算法里一般采用回退机制处理Atomic的CAS竞争
对死锁免疫的同步机制
目标:相对阻塞算法,减少线程切换开销、减少锁的竞争等。
也是Lock-free,即无锁编程
目前实现的常见数据结构:栈,队列,哈希表。参考代码:
ConcurrentLinkedQueue:
一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中
时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列获取操作从队列头部获得
元素。当多个线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许使
用 null 元素。
public boolean offer(E e) {
        if (e == null) throw new NullPointerException();
        Node n = new Node(e, null);
        for (;;) {
            Node t = tail;
            Node s = t.getNext();
            if (t == tail) {
                if (s == null) {
                    if (t.casNext(s, n)) {
                        casTail(t, n);
                        return true;
                    }
                } else {
                    casTail(t, s);
                }
            }
        }
    }

第65页


无锁栈算法:Treiber算法
改进版:http://research.microsoft.com/en-us/um/cambridge/projects/terminator/popl09.pdf

第66页


无锁队列算法:MS-Queue算法
论文地址:http://www.research.ibm.com/people/m/michael/podc-1996.pdf
    M S - q u e u e 算法是1 9 9 6 年由M a g e d . M .Michael and M. L. Scott提出的,是最为经典的并发FIFO队列上的算法,目前很多对并发FIFO队列的研究都是基于这个算法来加以改进的。

    MS-queue算法的队列用一个单链表来实现,包含两个基本的操作,enquene()和dequene() ,新节点总是从队尾最后一个元素后面加入队列,节点元素总是从队头删除。包含两个指针,head和tail,head总是自相链表头部的节点,指向的这个节点被当作是哑节点或哨兵节点,它保存的值是多少并无意义;tail总是指向链表中的一个节点,不一定是队尾元素。每个节点包含两个数据域值信息,即存放的数值信息和指向下一个节点的指针。每个指针对象,除了包含一个指向节点的指针外,还包含一个时间戳,初试时时戳为零,每修改一次指针,时戳增加一,在64位系统中,无需考虑时戳溢出的影响。

第67页


无锁队列算法:Optitmistic算法
    Optimistic算法对于上面提到的MS-queue算法的改进就在于使用普通的store指令代替代价昂贵的CAS指令。
    Optimistic算法的高效性在于使用双向链表表示队列,并且入队和出队操作都只需要一次成功的CAS操作。该算法保证链表总是连接的,next指针总是一致的,当prev指针出现不一致时通过调用fixList方法能够恢复到一致性状态。
    同MS-queue算法一样,optimistic算法也用到了原子化的指令Compare-and-swap(CAS),CAS(a,p,n),原子化的将内存地址a中的值与p进行比较,如果二者相等,就将n写入地址a中并返回true,否则返回false。由于optimistic算法使用了CAS指令,所以经典的ABA问题同样会出现,解决方案同MS-queue相同,即使用标签机制。
论文地址:http://nedko.arnaudov.name/soft/L17_Fober.pdf

第68页


Atomic实现
public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
当 import sun.misc.Unsafe; 这个的时候,就因为各种问题(例如:专利)看不到源码了。

第69页


好东东:AtomicReference
Lock-free的数据结构就靠这个了,无论你喜欢与否,玩无锁编程,你都绕不开这个类。看amino框架的源码,你会发现这个妞无处不在。

当然,还是AtomicInteger比较实用,多线程计数的时候,你会喜欢的。

第70页

编程实践:使用更优的锁
Jdk1.6已经优化了synchronized,

第71页

编程实践:使用更优的锁






ReentrantLock比较内部锁在JDK的性能提升对比
Jdk1.6已经优化了synchronized,

第72页

编程实践:使用更优的锁






读-写锁对比互斥锁ReentrantLock的性能

第73页

编程实践:缩小锁的范围
减少线程把持锁的时间
避免在临界区进行耗时计算
常见做法1:缩小同步快
常见做法2:把一个同步块分拆成多个
需要保证业务逻辑正确为前提

第74页

编程实践:避免热点域
热点域:每次操作,都需要访问修改的fields
eg. ConcurrentHashMap的size计算问题

第75页

编程实践:使用不变和Thread Local 的数据
不变数据,即Immutable类型数据、在其生命周期中始终保持不变,可以安全地在每个线程中复制一份以便快速读取。
ThreadLocal数据,只被线程本身使用,因此不存在不同线程之间的共享数据的问题。

第76页

编程实践:使用高并发容器
J.U.C的高效地线程安全的并发容器
Amino提供更多非阻塞的容器

第77页

编程实践:高速缓存计算结果
利用空间换时间
避免了重复计算相同的数据

第78页

编程实践:文档化对外接口的同步策略
如果一个类没有明确指明,就不要假设它是线程安全的
java.text.SimpleDateFormat并不是线程安全的,然而直到JDK1.4以前的Javadoc,都忽略了提及这一点,

第79页

编程实践:安全发布
@NotThreadSafe
public class UnsafeLazyInitialization {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null)
            resource = new Resource();  // unsafe publication
        return resource;
    }
}
@ThreadSafe
public class SafeLazyInitialization {
    private static Resource resource;

    public  synchronized  static Resource getInstance() {
        if (resource == null)
            resource = new Resource();
        return resource;
    }
}

第80页

编程实践:安全发布
@ThreadSafe
public class EagerInitialization {
    private static Resource resource  = new Resource();

    public static Resource getResource() { return resource; }
}
@ThreadSafe
public class ResourceFactory {
     private static class ResourceHolder {
         public static Resource resource = new Resource();
     }

     public static Resource getResource() {
         return  ResourceHolder.resource ;
     }
}
Jdk1.6已经优化了synchronized,

第81页

编程实践:安全发布
@NotThreadSafe
public class DoubleCheckedLocking {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null) {
            synchronized (DoubleCheckedLocking.class) {
                if (resource == null)
                    resource = new Resource();
            }
        }
        return resource;
    }
}
Jdk1.6已经优化了synchronized,

第82页

编程实践:利用成熟的框架
J.U.C
Amino
http://amino-cbbs.sourceforge.net
  (1)、Data Structures
(论文:http://www.research.ibm.com/people/m/michael/
spaa2002.pdf
http://citeseerx.ist.psu.edu/viewdoc/download?doi=
                          10.1.1.104.8774&rep=rep1&type=pdf)
LockFreeList、LockFreeSet、LockFreeOrderedList、
LockFreeDeque、LockFreeBlockQueue、ParallelRBTree
(2)、Parallel Patterns & functions
MasterWorker(类似ExecutorService)、WorkStealingScheduler
Concurrent Building Blocks 
1. Data Structures: A set of lockfree collection classes. Since these datastructures were developed using lockfree algorithms, they enjoy some of the basic lockfree properties like, immunity from different types of deadlocks, immunity for priority inversion, etc.
2. Patterns and Scheduling Algorithms: Most application parallelization efforts follow one or more of a number of well known parallel computation patterns. We provide a set of patterns that developers can directly leverage to build parallel applications. The patterns we propose to provide will include (but not limited to): Master-Worker, Map-reduce, Divide and conquer, Pipeline, etc. We also plan to provide a set of schedulers. The schedulers can be used in conjunction with the patterns classes.
3. Parallel implementations of general-purpose functions: Example of functions to include, but not limited to:
     1. String, Sequence and Array functions: Sort, Search, Merge, Rank, Compare, Reverse, Shuffle, Rotate, Median, etc.
     2. Tree and Graph functions: Connected Components, Spanning Trees, Shortest Path, Graph Coloring, etc.
4. Atomics, STM, etc.
     1. Deliver a C++ implementation of atomics. This implementation will be based on the draft of the C++ standards definition of the interface for atomics.
     2. Deliver an open, flexible implementation of Software Transactional Memory.
     
STM(Software transactional memory): In computer science, software transactional memory (STM) is a concurrency control mechanism analogous to database transactions for controlling access to shared memory in concurrent computing. It is an alternative to lock-based synchronization. A transaction in this context is a piece of code that executes a series of reads and writes to shared memory. These reads and writes logically occur at a single instant in time; intermediate states are not visible to other (successful) transactions. The idea of providing hardware support for transactions originated in a 1986 paper and patent by Tom Knight[1]. The idea was popularized by Maurice Herlihy and J. Eliot B. Moss[2]. In 1995 Nir Shavit and Dan Touitou extended this idea to software-only transactional memory (STM)[3]. STM has recently been the focus of intense research and support for practical implementations is growing.

Now Amino is under active development and we've got several golden components such as deque, queue, etc. Although some of our components are not best yet. It's our target to become a standare highly-scalable library for Java/C++ programmer.
Using Amino Java Components
Amino Java components depend on JDK version 6. Some components can be easily used in lower version. Some other compoents, such as Deque, implement an interface of JDK 6 standard library. These components can only run on JDK version 6 and later. Refer Java components quick startguide for more details. 

LockFreeList a lock-free linked list,ref. http://www.research.ibm.com/people/m/michael/spaa-2002.pdf
             This lock-free linked list is an unbounded thread-safe linked list. A LockFreeList is an appropriate choice when many threads will share
             access to a common collection. This list does not permit null element.
             This is a lock-free implementation intended for highly scalable add, remove
 * and contains which is thread safe. All method related to index is not
 * implemented. Add() will add the element to the head of the list which is
 * different with the normal list.
 
LockFreeOrderedList extends LockFreeList, ref. http://www.research.ibm.com/people/m/michael/spaa-2002.pdf
                    An unbounded thread-safe linked list which its element is ordered.
                    A LockFreeOrderedList is an appropriate choice when many threads
 * will share access to a common collection. This list does not permit
 * null elements. All elements in the list is ordered according to
 * compare(), This is a lock-free implementation intended for highly scalable add, remove
 * and contains which is thread safe. All mothed related to index is not thread
 * safe. Add() will add the element to the head of the list which is different
 * with the normal list.
LockFreeSet ref. http://www.research.ibm.com/people/m/michael/spaa-2002.pdf
              The internal data structure is a single linked list, which uses the same * algorithm as {@link LockFreeOrderedList}. Elements are sorted by "binary * reversal" of hash of elements. Additionally, an array of dummy nodes is * stored to allow quick access to elements in the middle of elements. Elements * are wrapped by {@link HashLinkNode} before stored into set.       
LockFreeDeque ref paper: CAS-Based Lock-Free Algorithm for Shared Deques By Maged M. Michael
              双向队列
EBDeque This deque add elimination mechanism to deal with high contention rate
 * scenario. Please read about {@link org.amino.utility.EliminationArray} to get
 * more information. If we don't consider elimination backoff, this class
 * implements the same algorithm as {@link org.amino.ds.lockfree.LockFreeDeque} 
   use EliminationArray 
EBStack implements IStack,use EliminationArray ,ref.  A Scalable Lock-free Stack Algorithm


EliminationArray A global elimination array class for several data structures. It can be used * to reducing number of modification to central data structure. The idea comes * from following observation: *  * 
If two threads execute push() or pop() operation on a stack, * there is no need to modify the stack at all. We can simply transfer object * from push() to the pop() and both operations succeed.

  ref.  A Scalable Lock-free Stack Algorithm
  
HakanDeque ref.  http://www.cs.chalmers.se/~dcs/ConcurrentDataStructures/phd_chap7.pdf 

LockFreeBlockQueue 方法采用cas实现,不加锁,不同于LinkedBlockingDeque,采用加锁策略。

LockFreeDictionary ref.  Scalable and Lock-Free Concurrent Dictionaries By Hakan Sundell and Philippas Tsigas

LockFreePriorityQueue ref. Fast and Lock-Free Concurrent Priority Queues for Multi-Thread Systems By
 * Hakan Sundell and Philippas Tsigas,支持Comparator

LockFreeVector ref. Lock-free Dynamically Resizable Arrays

ParallelRBTree This is an implementation of a relaxed balanced red-black tree data structure.
              ref. http://citeseer.ist.psu.edu/hanke97relaxed.html and
 * http://citeseer.ist.psu.edu/400640.html  The tree implemented here is a leaf-oriented binary search trees, which are
 * full binary trees (each node has either two or no children). 
 
GraphAlg getStrongComponents(获取有向图强连通子集) getConnectedComponents(获取无向图强连通子集)
         getMST(获取最小生成数) getShortestPath(获取最短路径)
ParallelPrefix ref. http://ocw.mit.edu/NR/rdonlyres/Mathematics/18-337JSpring-2005/95505ED3-630E-4B20-BB66-2FB14108FD39/0/lec4.pdf
ParallelScanner 

MultiCAS http://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-579.pdf

第83页

编程实践:利用成熟的框架
(3)、Parallel functions
GraphAlg、ParallelPrefix、ParallelScanner、QuickSorter
(4)、Atomics and STM
MultiCAS、LockFreeBSTree
Jdk1.6已经优化了synchronized,

第84页

书籍推荐:

第85页

Q&A

第86页

支持文件格式:*.pdf
上传最后阶段需要进行在线转换,可能需要1~2分钟,请耐心等待。