SlideShare ist ein Scribd-Unternehmen logo
1 von 86
Downloaden Sie, um offline zu lesen
Java  并发编程 龙浩
在一个 list 中有过亿条的 Integer 类型的值,如何更快的计算这些值的总和? 一个计算的问题 简单的方法:更快的 CPU 来遍历 靠谱的方法:分而治之来处理 进一步的方法: Fork/jion
简单的方法靠谱么? 免费午餐已经结束——软件历史性地向并发靠拢 http://news.csdn.net/n/20071219/111880.html 软层次上:遍历是不靠谱的, for 小学生了!
靠谱的方法简单么?(分而治之) list1 list2 list3 Concurrency 那帮 Java 大神在他们书中说: 在对性能的追求很可能是并发 bug 唯一最大的来源! So : 同样不是免费的午餐,需要学习和批量实践。 Thread Thread Thread
目录 线程 并发编程 (juc) 线程监控工具 编程思想和实践 Fork/Jion 框架
Visibility :通过并发线程修改变量值 ,  必须将线程变量同步回主存后 ,  其他线程才能访问到。 Ordering :通过 java 提供的同步机制或 volatile 关键字 ,  来保证内存的访问顺序。 Cache coherency  :它是一种管理多处理器系统的高速缓存区结构,其可以保证数据在高速缓存区到内存的传输中不会丢失或重复。  Happens-before ordering : synchronized,volatile,final,java.util.concurrent.lock|atomic 线程:先让路给内存模型 这里有详述: http://is.gd/c8fhE  ( 别迷恋哥,哥只是传说! )
内存中的可见部分 Stack-1 Stack-2 Stack-3 Globals Heap
线程: synchronized 保证原子性和可见性 内 部 锁 分 离 锁 分 拆 锁
线程: 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 Object],[object Object],[object Object],[object Object]
分拆前:思考问题,顺便教你一招! 分拆不了人,工具还不能分拆么?对,买 3 个手机去……
线程:分拆锁
线程:分离锁 分离锁负面作用:对容器加锁,进行独占访问更加困难,并且更加昂贵了。 内存使用的问题: sina 就曾经因为在 Action 层使用 ConcurrentHashMap 而导致内存使用过大,修改 array 后竟然单台服务器节省 2G 。
线程: 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(&quot;pg&quot;)){t.setName(&quot; ceshi &quot;);} } 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); } }
线程:可见性 volatile 关键字: 1 :简化实现或者同步策略验证的时候来使用它; 2 :确保引用对象的可见性; 3 :标示重要的生命周期的事件,例如:开始或者关闭。 脆弱的 volatile 的使用条件: 1 :写入变量不依赖变量的当前值,或者能够保证只有单一的线程修改变量的值; 2 :变量不需要和其他变量共同参与不变约束; 3 :访问变量时不需要其他原因需要加锁。 private  volatile  boolean isInterrupted = false;
任务的取消和线程超时
线程中断
教父 Joshua Bloch 说线程: ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
目录 线程 并发编程 (juc) 线程监控工具 编程思想和实践 Fork/Jion 框架
开始并发编程了
行动之前,拜神先 ,[object Object],[object Object],[object Object],[object Object],Doug Lea
并发编程:三大定律( 1 ) 讨论的是加速比( speedup )的问题
并发编程:三大定律( 2 ) ,[object Object]
并发编程:三大定律( 3 ) ,[object Object]
总结不是 API ,是寂寞!
来个高清无码版 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
ThreadPoolExecutor :自己动手,丰衣足食! public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit. MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } 1 :线程池的大小最好是设定好,因为 JDK 的管理内存毕竟是有限的; 2 :使用结束,需要关闭线程池; 3 :  Runtime. getRuntime().addShutdownHook( hook);  对不能正常关闭的 线程做好相关的记录。
Executors : ExecutorService 严重注意:别设置线程池无限大小
入门版: CompletionService 生产者消费者模式的简要实现版本。
双剑合璧: Future+Callable
任务池:  ScheduledExecutorService 计划任务执行相关的操作, 使用 java 真幸福,选择多多!
阻塞队列: BlockingQueue Kaopuability :插入( offer ) ; 移除( poll ) 抛出异常 特殊值 阻塞 超时 插入 add(e) offer(e) put(e) offer(e, time, unit) 移除 remove() poll() take() poll(time, unit) 检查 element() peek() 不可用 不可用
BlockingQueue  的诸侯领地 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
BlockingDeque: 双端队列 第一个元素(头部) 抛出异常 特殊值 阻塞 超时期 插入 addFirst(e) offerFirst(e) putFirst(e) offerFirst(e, time, unit) 移除 removeFirst() pollFirst() takeFirst() pollFirst(time, unit) 检查 getFirst() peekFirst() 不适用 不适用 最后一个元素(尾部) 抛出异常 特殊值 阻塞 超时期 插入 addLast(e) offerLast(e) putLast(e) offerLast(e, time, unit) 移除 removeLast() pollLast() takeLast() pollLast(time, unit) 检查 getLast() peekLast() 不适用 不适用
并发集合 : 你值得拥有 同步的不是 Map, 是凤姐!
ConcurrentHashMap: 解放军 38 军 你那飘逸的同步,分离锁的设计,再 hash 算法以及游离于多个 Segment 的耍心跳的各种操作,都深深的吸引了我。 详细设计细节: http://www.ibm.com/developerworks/java/library/j-jtp08223/
比较 Map 的性能
CopyOnWriteArray{List,Set} 当读操作远远大于写操作的时候,考虑用这个并发集合。例如:维护监听器的集合。注意:其频繁写的效率可能低的惊人。 奇技淫巧:屏蔽 add 带来的数组拷贝; public List<String> array = new ArrayList<String>(); public List<String> list = new CopyOnWriteArrayList<String>(array);
同步器:四大金刚
闭锁: CountDownLatch 等待启动信号 等待完成信号 继续 启动信号 + 完成信号的模式 N 部分锁存器倒计数模式; 当线程必须用这种方法反复倒计数时,可改为使用  CyclicBarrier 典型应用:手动控制事务,从数据库读取多份数据做初始化; 线程 A 获得等待启动信号 线程 B 获得等待启动信号 线程 C 获得等待启动信号 线程 A 运行,递减锁存器的计数 线程 B 运行,递减锁存器的计数 线程 C 运行,递减锁存器的计数
关卡: 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.  A B C
信号量: Semaphore 获取信号(  acquire(); )
交换器: Exchanger ,[object Object],[object Object],至今我没有用过
锁云:你的柔情我永远不懂 内部锁 互斥锁 分离锁 分拆锁 闭锁 独占锁 读写锁 顺序锁
互斥锁:   ReentrantLock ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
互斥锁(公平与非公平)和内部锁性能对比图 结论:非公平互斥锁和内部锁性能在 jdk6_17 下性能基本一样。 测试机:酷睿 2.66 双核, 2G 内存, win7
读写锁:   ReadWriteLock ReadWriteLock  维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有  writer ,读取锁可以由多个  reader  线程同时保持。写入锁是独占的。 ReentrantReadWriteLock ReadLock  WriteLock  线程 1 线程 2 线程 3
高深: AbstractQueuedSynchronizer ,[object Object],[object Object],[object Object],[object Object],[object Object]
目录 线程 并发编程 (juc) 线程监控工具 编程思想和实践 Fork/Jion 框架
Fork/Join Framework (1) Work Stealing
Fork/Join Framework ,[object Object],[object Object],[object Object],[object Object],Doug Lea 论文: http://gee.cs.oswego.edu/dl/papers/fj.pdf
Fork/Join  的案例:求数组中的最大值
Fork/Join  运行测试结果 表  1.  在不同系统上从  500k  个元素的数组中运行  select-max  的结果 fork-join  池中的线程数量与可用的硬件线程(内核数乘以每个内核中的线程数)相等 阙值  = 500k 阙值  = 50k 阙值  = 5k 阙值  = 500 阙值  = -50 Pentium-4 HT ( 2  个线程) 1.0 1.07 1.02 .82 .2 Dual-Xeon HT ( 4  个线程) .88 3.02 3.2 2.22 .43 8-way Opteron ( 8  个线程) 1.0 5.29 5.73 4.53 2.03 8-core Niagara ( 32  个线程) .98 10.46 17.21 15.34 6.49
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
目录 线程 并发编程 (juc) 线程监控工具 编程思想和实践 Fork/Jion 框架
线程监控: DIY Windows  下面 DIY 方式很多, txt 编辑器都是好东西
线程监控: Jconsole
线程监控: VisualVm 本地 下载地址: https://visualvm.dev.java.net/download.html JDK1.6 之后自带了这个攻击,在 java_home/bin 下面; 喜新厌旧的 GGDDJJMM 去上述地址下载吧!
内存监控: VisualVm 远程
Thread Dump Analyzer https://tda.dev.java.net/
目录 线程 并发编程 (juc) 线程监控工具 编程思想和实践 Fork/Jion 框架
基本思想: CAS 操作 ,[object Object],[object Object]
基本思想: Atomic 原子类 ,[object Object],[object Object],[object Object],[object Object],[object Object]
基本思想:非阻塞算法 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
无锁栈算法: Treiber 算法 改进版: http://research.microsoft.com/en-us/um/cambridge/projects/terminator/popl09.pdf
无锁队列算法: 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 位系统中,无需考虑时戳溢出的影响。
无锁队列算法: 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
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;  这个的时候,就因为各种问题(例如:专利)看不到源码了。
好东东: AtomicReference Lock-free 的数据结构就靠这个了,无论你喜欢与否,玩无锁编程,你都绕不开这个类。看 amino 框架的源码,你会发现这个妞无处不在。 当然,还是 AtomicInteger 比较实用,多线程计数的时候,你会喜欢的。
编程实践:使用更优的锁
编程实践:使用更优的锁 ReentrantLock 比较内部锁在 JDK 的性能提升对比
编程实践:使用更优的锁 读-写锁对比互斥锁 ReentrantLock 的性能
编程实践:缩小锁的范围 ,[object Object],[object Object],[object Object],[object Object],[object Object]
编程实践:避免热点域 ,[object Object],[object Object]
编程实践: 使用不变和 Thread Local  的数据 ,[object Object],[object Object]
编程实践: 使用高并发容器 ,[object Object],[object Object]
编程实践: 高速缓存计算结果 ,[object Object],[object Object]
编程实践: 文档化对外接口的同步策略 ,[object Object]
编程实践: 安全发布 @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; } }
编程实践: 安全发布 @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 ; } }
编程实践: 安全发布 @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; } }
编程实践: 利用成熟的框架 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
编程实践: 利用成熟的框架   (3) 、 Parallel functions     GraphAlg 、 ParallelPrefix 、 ParallelScanner 、 QuickSorter   (4) 、 Atomics and STM     MultiCAS 、 LockFreeBSTree
书籍推荐:
Q&A
 

Weitere ähnliche Inhalte

Was ist angesagt?

Java多线程设计模式
Java多线程设计模式Java多线程设计模式
Java多线程设计模式Tony Deng
 
台南好想工作室-想知道講座-ES6 進入天堂的窄門Promise
台南好想工作室-想知道講座-ES6 進入天堂的窄門Promise台南好想工作室-想知道講座-ES6 進入天堂的窄門Promise
台南好想工作室-想知道講座-ES6 進入天堂的窄門PromiseZenChou2
 
Java并发核心编程
Java并发核心编程Java并发核心编程
Java并发核心编程wavefly
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closureswang hongjiang
 
Java多线程:驾驭Synchronize的方法
Java多线程:驾驭Synchronize的方法Java多线程:驾驭Synchronize的方法
Java多线程:驾驭Synchronize的方法yiditushe
 
Mysql展示功能与源码对应
Mysql展示功能与源码对应Mysql展示功能与源码对应
Mysql展示功能与源码对应zhaolinjnu
 
Jni攻略之八――操作对象的构造方法
Jni攻略之八――操作对象的构造方法Jni攻略之八――操作对象的构造方法
Jni攻略之八――操作对象的构造方法yiditushe
 
IOS入门分享
IOS入门分享IOS入门分享
IOS入门分享zenyuhao
 
Reactive X 响应式编程
Reactive X 响应式编程Reactive X 响应式编程
Reactive X 响应式编程Jun Liu
 
Enqueue Lock介绍.ppt
Enqueue Lock介绍.pptEnqueue Lock介绍.ppt
Enqueue Lock介绍.pptjames tong
 
OpenEJB - 另一個選擇
OpenEJB - 另一個選擇OpenEJB - 另一個選擇
OpenEJB - 另一個選擇Justin Lin
 
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践yiditushe
 
Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题yiditushe
 

Was ist angesagt? (20)

Java多线程设计模式
Java多线程设计模式Java多线程设计模式
Java多线程设计模式
 
Javascript 闭包
Javascript 闭包Javascript 闭包
Javascript 闭包
 
Ali-tomcat
Ali-tomcatAli-tomcat
Ali-tomcat
 
Jvm内存管理基础
Jvm内存管理基础Jvm内存管理基础
Jvm内存管理基础
 
台南好想工作室-想知道講座-ES6 進入天堂的窄門Promise
台南好想工作室-想知道講座-ES6 進入天堂的窄門Promise台南好想工作室-想知道講座-ES6 進入天堂的窄門Promise
台南好想工作室-想知道講座-ES6 進入天堂的窄門Promise
 
Java并发核心编程
Java并发核心编程Java并发核心编程
Java并发核心编程
 
泛型总结
泛型总结泛型总结
泛型总结
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
 
Java多线程:驾驭Synchronize的方法
Java多线程:驾驭Synchronize的方法Java多线程:驾驭Synchronize的方法
Java多线程:驾驭Synchronize的方法
 
Mysql展示功能与源码对应
Mysql展示功能与源码对应Mysql展示功能与源码对应
Mysql展示功能与源码对应
 
Jni攻略之八――操作对象的构造方法
Jni攻略之八――操作对象的构造方法Jni攻略之八――操作对象的构造方法
Jni攻略之八――操作对象的构造方法
 
并发控制
并发控制并发控制
并发控制
 
IOS入门分享
IOS入门分享IOS入门分享
IOS入门分享
 
Reactive X 响应式编程
Reactive X 响应式编程Reactive X 响应式编程
Reactive X 响应式编程
 
Enqueue Lock介绍.ppt
Enqueue Lock介绍.pptEnqueue Lock介绍.ppt
Enqueue Lock介绍.ppt
 
OpenEJB - 另一個選擇
OpenEJB - 另一個選擇OpenEJB - 另一個選擇
OpenEJB - 另一個選擇
 
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
 
Exodus2 大局观
Exodus2 大局观Exodus2 大局观
Exodus2 大局观
 
Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题
 
Java Thread
Java ThreadJava Thread
Java Thread
 

Ähnlich wie Java并发编程培训

Java并发编程实践
Java并发编程实践Java并发编程实践
Java并发编程实践sharewind
 
Java程序员面试之葵花宝典
Java程序员面试之葵花宝典Java程序员面试之葵花宝典
Java程序员面试之葵花宝典yiditushe
 
Java面试宝典
Java面试宝典Java面试宝典
Java面试宝典ma tao
 
Java多线程编程详解
Java多线程编程详解Java多线程编程详解
Java多线程编程详解yiditushe
 
Notes of jcip
Notes of jcipNotes of jcip
Notes of jcipDai Jun
 
基于协程的网络开发框架的设计与实现
基于协程的网络开发框架的设计与实现基于协程的网络开发框架的设计与实现
基于协程的网络开发框架的设计与实现mysqlops
 
Showinnodbstatus公开
Showinnodbstatus公开Showinnodbstatus公开
Showinnodbstatus公开longxibendi
 
并发编程实践与思考
并发编程实践与思考并发编程实践与思考
并发编程实践与思考promise6522
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7javatwo2011
 
中远公司 Java培训资料
中远公司  Java培训资料中远公司  Java培训资料
中远公司 Java培训资料yiditushe
 
并发编程交流
并发编程交流并发编程交流
并发编程交流bluedavy lin
 
Java面试知识
Java面试知识Java面试知识
Java面试知识yiditushe
 
IKVM.NET 深入敵營的 Java
IKVM.NET 深入敵營的 JavaIKVM.NET 深入敵營的 Java
IKVM.NET 深入敵營的 Java建興 王
 
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJustin Lin
 
最新Java技术内存模型
最新Java技术内存模型最新Java技术内存模型
最新Java技术内存模型yiditushe
 
網站設計100步
網站設計100步網站設計100步
網站設計100步evercislide
 
2014暑期訓練之Linux kernel power
2014暑期訓練之Linux kernel power2014暑期訓練之Linux kernel power
2014暑期訓練之Linux kernel power冠宇 陳
 

Ähnlich wie Java并发编程培训 (20)

Java并发编程实践
Java并发编程实践Java并发编程实践
Java并发编程实践
 
Java程序员面试之葵花宝典
Java程序员面试之葵花宝典Java程序员面试之葵花宝典
Java程序员面试之葵花宝典
 
Java面试宝典
Java面试宝典Java面试宝典
Java面试宝典
 
Clojure的魅力
Clojure的魅力Clojure的魅力
Clojure的魅力
 
Java多线程编程详解
Java多线程编程详解Java多线程编程详解
Java多线程编程详解
 
Notes of jcip
Notes of jcipNotes of jcip
Notes of jcip
 
基于协程的网络开发框架的设计与实现
基于协程的网络开发框架的设计与实现基于协程的网络开发框架的设计与实现
基于协程的网络开发框架的设计与实现
 
Showinnodbstatus公开
Showinnodbstatus公开Showinnodbstatus公开
Showinnodbstatus公开
 
并发编程实践与思考
并发编程实践与思考并发编程实践与思考
并发编程实践与思考
 
中软
中软中软
中软
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7
 
中远公司 Java培训资料
中远公司  Java培训资料中远公司  Java培训资料
中远公司 Java培训资料
 
并发编程交流
并发编程交流并发编程交流
并发编程交流
 
Java面试知识
Java面试知识Java面试知识
Java面试知识
 
IKVM.NET 深入敵營的 Java
IKVM.NET 深入敵營的 JavaIKVM.NET 深入敵營的 Java
IKVM.NET 深入敵營的 Java
 
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
 
最新Java技术内存模型
最新Java技术内存模型最新Java技术内存模型
最新Java技术内存模型
 
網站設計100步
網站設計100步網站設計100步
網站設計100步
 
Zoo keeper
Zoo keeperZoo keeper
Zoo keeper
 
2014暑期訓練之Linux kernel power
2014暑期訓練之Linux kernel power2014暑期訓練之Linux kernel power
2014暑期訓練之Linux kernel power
 

Mehr von longhao

手机上的硬件设备及典型App
手机上的硬件设备及典型App手机上的硬件设备及典型App
手机上的硬件设备及典型Applonghao
 
Node.js长连接开发实践
Node.js长连接开发实践Node.js长连接开发实践
Node.js长连接开发实践longhao
 
Vim get start_1.0
Vim get start_1.0Vim get start_1.0
Vim get start_1.0longhao
 
无Ued产品的易用性讨论
无Ued产品的易用性讨论无Ued产品的易用性讨论
无Ued产品的易用性讨论longhao
 
Dean Keynote Ladis2009
Dean Keynote Ladis2009Dean Keynote Ladis2009
Dean Keynote Ladis2009longhao
 
产品部内部交流平台
产品部内部交流平台产品部内部交流平台
产品部内部交流平台longhao
 
借助社会化媒体的个人成长
借助社会化媒体的个人成长借助社会化媒体的个人成长
借助社会化媒体的个人成长longhao
 
高性能网站最佳实践
高性能网站最佳实践高性能网站最佳实践
高性能网站最佳实践longhao
 
软件重构
软件重构软件重构
软件重构longhao
 
透明计算与云计算
透明计算与云计算透明计算与云计算
透明计算与云计算longhao
 
Netputer
NetputerNetputer
Netputerlonghao
 

Mehr von longhao (12)

手机上的硬件设备及典型App
手机上的硬件设备及典型App手机上的硬件设备及典型App
手机上的硬件设备及典型App
 
Node.js长连接开发实践
Node.js长连接开发实践Node.js长连接开发实践
Node.js长连接开发实践
 
Vim get start_1.0
Vim get start_1.0Vim get start_1.0
Vim get start_1.0
 
无Ued产品的易用性讨论
无Ued产品的易用性讨论无Ued产品的易用性讨论
无Ued产品的易用性讨论
 
Dean Keynote Ladis2009
Dean Keynote Ladis2009Dean Keynote Ladis2009
Dean Keynote Ladis2009
 
产品部内部交流平台
产品部内部交流平台产品部内部交流平台
产品部内部交流平台
 
hadoop
hadoophadoop
hadoop
 
借助社会化媒体的个人成长
借助社会化媒体的个人成长借助社会化媒体的个人成长
借助社会化媒体的个人成长
 
高性能网站最佳实践
高性能网站最佳实践高性能网站最佳实践
高性能网站最佳实践
 
软件重构
软件重构软件重构
软件重构
 
透明计算与云计算
透明计算与云计算透明计算与云计算
透明计算与云计算
 
Netputer
NetputerNetputer
Netputer
 

Kürzlich hochgeladen

买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】黑客 接单【TG/微信qoqoqdqd】
 
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptxNCU MCL
 
20200808自營電商平台策略討論
20200808自營電商平台策略討論20200808自營電商平台策略討論
20200808自營電商平台策略討論Jamie (Taka) Wang
 
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxSymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxNCU MCL
 
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxSymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxNCU MCL
 
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptxNCU MCL
 
20200727_Insight workstation
20200727_Insight workstation20200727_Insight workstation
20200727_Insight workstationJamie (Taka) Wang
 
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptxNCU MCL
 
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptxNCU MCL
 

Kürzlich hochgeladen (17)

买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
 
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
 
20200808自營電商平台策略討論
20200808自營電商平台策略討論20200808自營電商平台策略討論
20200808自營電商平台策略討論
 
20200606_insight_Ignition
20200606_insight_Ignition20200606_insight_Ignition
20200606_insight_Ignition
 
20200607_insight_sync
20200607_insight_sync20200607_insight_sync
20200607_insight_sync
 
20200427_hardware
20200427_hardware20200427_hardware
20200427_hardware
 
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxSymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
 
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxSymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
 
20220113_product_day
20220113_product_day20220113_product_day
20220113_product_day
 
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
 
20200727_Insight workstation
20200727_Insight workstation20200727_Insight workstation
20200727_Insight workstation
 
20210105_量產技轉
20210105_量產技轉20210105_量產技轉
20210105_量產技轉
 
20200429_ec
20200429_ec20200429_ec
20200429_ec
 
20200602_insight_business
20200602_insight_business20200602_insight_business
20200602_insight_business
 
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
 
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
 
20200429_software
20200429_software20200429_software
20200429_software
 

Java并发编程培训

  • 2. 在一个 list 中有过亿条的 Integer 类型的值,如何更快的计算这些值的总和? 一个计算的问题 简单的方法:更快的 CPU 来遍历 靠谱的方法:分而治之来处理 进一步的方法: Fork/jion
  • 4. 靠谱的方法简单么?(分而治之) list1 list2 list3 Concurrency 那帮 Java 大神在他们书中说: 在对性能的追求很可能是并发 bug 唯一最大的来源! So : 同样不是免费的午餐,需要学习和批量实践。 Thread Thread Thread
  • 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 ( 别迷恋哥,哥只是传说! )
  • 8. 线程: synchronized 保证原子性和可见性 内 部 锁 分 离 锁 分 拆 锁
  • 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.
  • 10.
  • 13. 线程:分离锁 分离锁负面作用:对容器加锁,进行独占访问更加困难,并且更加昂贵了。 内存使用的问题: sina 就曾经因为在 Action 层使用 ConcurrentHashMap 而导致内存使用过大,修改 array 后竟然单台服务器节省 2G 。
  • 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(&quot;pg&quot;)){t.setName(&quot; ceshi &quot;);} } 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;
  • 18.
  • 19. 目录 线程 并发编程 (juc) 线程监控工具 编程思想和实践 Fork/Jion 框架
  • 21.
  • 22. 并发编程:三大定律( 1 ) 讨论的是加速比( speedup )的问题
  • 23.
  • 24.
  • 26.
  • 27. ThreadPoolExecutor :自己动手,丰衣足食! public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit. MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } 1 :线程池的大小最好是设定好,因为 JDK 的管理内存毕竟是有限的; 2 :使用结束,需要关闭线程池; 3 : Runtime. getRuntime().addShutdownHook( hook); 对不能正常关闭的 线程做好相关的记录。
  • 28. Executors : ExecutorService 严重注意:别设置线程池无限大小
  • 31. 任务池: ScheduledExecutorService 计划任务执行相关的操作, 使用 java 真幸福,选择多多!
  • 32. 阻塞队列: BlockingQueue Kaopuability :插入( offer ) ; 移除( poll ) 抛出异常 特殊值 阻塞 超时 插入 add(e) offer(e) put(e) offer(e, time, unit) 移除 remove() poll() take() poll(time, unit) 检查 element() peek() 不可用 不可用
  • 33.
  • 34. BlockingDeque: 双端队列 第一个元素(头部) 抛出异常 特殊值 阻塞 超时期 插入 addFirst(e) offerFirst(e) putFirst(e) offerFirst(e, time, unit) 移除 removeFirst() pollFirst() takeFirst() pollFirst(time, unit) 检查 getFirst() peekFirst() 不适用 不适用 最后一个元素(尾部) 抛出异常 特殊值 阻塞 超时期 插入 addLast(e) offerLast(e) putLast(e) offerLast(e, time, unit) 移除 removeLast() pollLast() takeLast() pollLast(time, unit) 检查 getLast() peekLast() 不适用 不适用
  • 35. 并发集合 : 你值得拥有 同步的不是 Map, 是凤姐!
  • 36. ConcurrentHashMap: 解放军 38 军 你那飘逸的同步,分离锁的设计,再 hash 算法以及游离于多个 Segment 的耍心跳的各种操作,都深深的吸引了我。 详细设计细节: http://www.ibm.com/developerworks/java/library/j-jtp08223/
  • 38. CopyOnWriteArray{List,Set} 当读操作远远大于写操作的时候,考虑用这个并发集合。例如:维护监听器的集合。注意:其频繁写的效率可能低的惊人。 奇技淫巧:屏蔽 add 带来的数组拷贝; public List<String> array = new ArrayList<String>(); public List<String> list = new CopyOnWriteArrayList<String>(array);
  • 40. 闭锁: CountDownLatch 等待启动信号 等待完成信号 继续 启动信号 + 完成信号的模式 N 部分锁存器倒计数模式; 当线程必须用这种方法反复倒计数时,可改为使用 CyclicBarrier 典型应用:手动控制事务,从数据库读取多份数据做初始化; 线程 A 获得等待启动信号 线程 B 获得等待启动信号 线程 C 获得等待启动信号 线程 A 运行,递减锁存器的计数 线程 B 运行,递减锁存器的计数 线程 C 运行,递减锁存器的计数
  • 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. A B C
  • 43.
  • 44. 锁云:你的柔情我永远不懂 内部锁 互斥锁 分离锁 分拆锁 闭锁 独占锁 读写锁 顺序锁
  • 45.
  • 46. 互斥锁(公平与非公平)和内部锁性能对比图 结论:非公平互斥锁和内部锁性能在 jdk6_17 下性能基本一样。 测试机:酷睿 2.66 双核, 2G 内存, win7
  • 47. 读写锁: ReadWriteLock ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer ,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。 ReentrantReadWriteLock ReadLock WriteLock 线程 1 线程 2 线程 3
  • 48.
  • 49. 目录 线程 并发编程 (juc) 线程监控工具 编程思想和实践 Fork/Jion 框架
  • 50. Fork/Join Framework (1) Work Stealing
  • 51.
  • 53. Fork/Join 运行测试结果 表 1. 在不同系统上从 500k 个元素的数组中运行 select-max 的结果 fork-join 池中的线程数量与可用的硬件线程(内核数乘以每个内核中的线程数)相等 阙值 = 500k 阙值 = 50k 阙值 = 5k 阙值 = 500 阙值 = -50 Pentium-4 HT ( 2 个线程) 1.0 1.07 1.02 .82 .2 Dual-Xeon HT ( 4 个线程) .88 3.02 3.2 2.22 .43 8-way Opteron ( 8 个线程) 1.0 5.29 5.73 4.53 2.03 8-core Niagara ( 32 个线程) .98 10.46 17.21 15.34 6.49
  • 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 编辑器都是好东西
  • 58. 线程监控: VisualVm 本地 下载地址: https://visualvm.dev.java.net/download.html JDK1.6 之后自带了这个攻击,在 java_home/bin 下面; 喜新厌旧的 GGDDJJMM 去上述地址下载吧!
  • 60. Thread Dump Analyzer https://tda.dev.java.net/
  • 61. 目录 线程 并发编程 (juc) 线程监控工具 编程思想和实践 Fork/Jion 框架
  • 62.
  • 63.
  • 64.
  • 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 比较实用,多线程计数的时候,你会喜欢的。
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 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 ; } }
  • 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; } }
  • 82.
  • 83. 编程实践: 利用成熟的框架   (3) 、 Parallel functions     GraphAlg 、 ParallelPrefix 、 ParallelScanner 、 QuickSorter   (4) 、 Atomics and STM     MultiCAS 、 LockFreeBSTree
  • 85. Q&A
  • 86.  

Hinweis der Redaktion

  1. 图 1 :为什么没有 10GHz 的芯片呢?受制于一些物理学问题,如散热(发热量太大且难以驱散)、功耗(太高)以及泄漏问题。 参考: NetBurst 的继承者 Core 微处理器架构技术解析 http://diy.yesky.com/cpu/389/2340389.shtml?3093 图 2 :在 IDF05 ( Intel Developer Forum 2005 )上。 Intel 首席执行官 Craig Barrett 就取消 4GHz 芯片计划一事,半开玩笑当众单膝下跪致歉。
  2. 别迷信内存模型的架构,传说 SUN 的那帮专家都有时候被专家搞迷糊了。
  3. 所有内存都是共享的么? 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.
  4. public synchronized static int getAge(int i){ return i; } public synchronized String name(){ return &amp;quot;longhao&amp;quot;; } public void modifyHeight(){ synchronized(this){ //do something } //do something }
  5. 中文翻译为管程。 synchronized 、 Object.wait() 、 Object.notify() 的底层实现。但是 java 原生提供的 monitor 不完整,因为没有提供 Condition , Object 本身隐含提供一 Condition 。 http://www.artima.com/insidejvm/ed2/threadsynch.html
  6. 这里详细介绍: http://www.ibm.com/developerworks/cn/java/j-lo-lock/ 不过瘾的看这个: http://book.csdn.net/bookfiles/398/10039814664.shtml
  7. 这里详细介绍: http://www.ibm.com/developerworks/cn/java/j-lo-lock/ 不过瘾的看这个: http://book.csdn.net/bookfiles/398/10039814664.shtml
  8. 注意: wait,sleep,yield,join 可都是 native 的,抛出 InterruptedException 。
  9. 注意: wait,sleep,yield,join 都是 native 的,抛出 InterruptedException 。
  10. 10 个老婆一个月也不能把儿子生出来。
  11. 如何更快的生 10 个孩子的问题。
  12. 在 Gustafson 定理 中,加速比与处理器数几乎呈线性关系,这是 Sun-Ni 定理中 G(p)=p 的情况;而如果 G(p)=1 ,则是表明工作量无增加,即 Amdahl 定理 中的情况。
  13. 存在一种算法 TimerWheel ,适用于大规模的定时器实现。这个算法最早是被设计用来实现 BSD 内核中定时器的,后来被广泛移植到诸如 ACE 等框架中,堪称 BSD 中经典算法之一,能针对定时器的各类常见操作提供接近常数时间的响应,且能根据需要很容易进行扩展。( TimerWheel 在 Java 5 中实现很简单)
  14. 循环数 / 线程数
  15. 目前的多处理器系统基本都支持原子指令,典型模式:首先从 V 中读取值 B ,由 A 生成新值 B ,然后使用 CAS 原子化地把 V 的值由 A 修改成 B ,并且期间不能有其他线程修改 V 的值, CAS 能够发现来自其他线程的干扰,所以即使不使用锁,也能解决原子化地读-写-改的问题
  16. 为了解决 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(&amp;quot;value&amp;quot;)); } 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. * * &lt;p&gt;May &lt;a href=&amp;quot;package-summary.html#Spurious&amp;quot;&gt;fail spuriously&lt;/a&gt; * 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; } }
  17. 目前实现的常见数据结构:栈,队列,哈希表。参考代码: ConcurrentLinkedQueue: 一个基于链接节点的无界线程安全队列。此队列按照 FIFO (先进先出)原则对元素进行排序。队列的头部 是队列中 时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列获取操作从队列头部获得 元素。当多个线程共享访问一个公共 collection 时, ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许使 用 null 元素。 public boolean offer(E e) { if (e == null ) throw new NullPointerException(); Node&lt;E&gt; n = new Node&lt;E&gt;(e, null ); for (;;) { Node&lt;E&gt; t = tail; Node&lt;E&gt; s = t.getNext(); if (t == tail) { if (s == null ) { if (t.casNext(s, n)) { casTail(t, n); return true ; } } else { casTail(t, s); } } } }
  18. Jdk1.6 已经优化了 synchronized ,
  19. Jdk1.6 已经优化了 synchronized ,
  20. java.text.SimpleDateFormat 并不是线程安全的,然而直到 JDK1.4 以前的 Javadoc ,都忽略了提及这一点,
  21. Jdk1.6 已经优化了 synchronized ,
  22. Jdk1.6 已经优化了 synchronized ,
  23. 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&apos;ve got several golden components such as deque, queue, etc. Although some of our components are not best yet. It&apos;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 &lt;tt&gt;LockFreeOrderedList&lt;/tt&gt; is an appropriate choice when many threads * will share access to a common collection. This list does not permit * &lt;tt&gt;null&lt;/tt&gt; 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 &amp;quot;binary * reversal&amp;quot; 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&apos;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: * * &lt;blockquote&gt;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.&lt;/blockquote&gt; 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
  24. Jdk1.6 已经优化了 synchronized ,