狠狠撸

狠狠撸Share a Scribd company logo
最新 Java? 技术内存
       模型                                           java.sun.com/javaone/sf




      Jeremy Manson 和 William Pugh
      马里兰大学
      http://www.cs.umd.edu/~pugh

1   | 2004 JavaOneSM Conference | Session TS-2331
听众

    ? 假设你熟悉基于 Java? 技术的线程(“ Java?
          线程”)的基础知识
            ─ 创建、启动和加入线程
            ─ 同步
            ─ wait 和 notifyAll




2   | 2004 JavaOneSM Conference | Session TS-2331
Java? 线程规范

    ? 修订为 JSR-133 的一部分
    ? 属于以下规范中的一部分
            ─ 最新 Java? 语言规范
            ─ 最新虚拟机规范
    ? 今天在此讨论是 JDK? 1.5 版本中的功能
            ─ 不是所有这些功能都能保证在以前版本中运行
            ─ 突破以前的线程规范
                   ─ 禁止许多 Java? 虚拟机执行优化




3   | 2004 JavaOneSM Conference | Session TS-2331
多线程系统中的安全问题

    ? 不要保留许多直觉假设
    ? 某些广泛使用的习惯用法并不安全
            ─ 最初的双重检查锁定用法
            ─ 检查用于线程结束的 non-volatile 标志
    ? 不能使用测试来检查错误
            ─ 有些异常情况仅在某些平台上出现
                   ─ 例如,多处理器
            ─ 异常情况很少并且不重复地出现




4   | 2004 JavaOneSM Conference | Session TS-2331
修订线程规范

    ? Java? 线程规范已历经重大修订
            ─ 多数修订是为适当地规范现有行为
            ─ 但行为方面有少数更改
    ? 目标
            ─ 清晰并且易于理解
            ─ 培植可靠的多线程代码
            ─ 可供高性能的 Java? 虚拟机使用
    ? 已影响 Java? 虚拟机
            ─ 以及已编写出的较差的现有代码
                   ─ 包括 Sun 的 JDK 部分


5   | 2004 JavaOneSM Conference | Session TS-2331
本次演讲……

    ? 用 Java? 语言描述构建同步阻塞和并发程序
            ─ 语言原语和 util.concurrent 抽象
    ? 说明正确同步化代码的意义
    ? 尽力使你确信,对于不同步代码的智能推断几
          乎肯定可以是错误的
            ─ 高效和可靠的程序不需要




6   | 2004 JavaOneSM Conference | Session TS-2331
本次演讲……

    ? 我们将主要讨论
            ─ 同步方法和阻塞
            ─ Volatile 域
    ? 同一原则适用于 JSR-166 锁定和原子性操作
    ? 还将讨论 final 域和不可变性




7   | 2004 JavaOneSM Conference | Session TS-2331
分类学

    ? 高级并发抽象
            ─ JSR-166 和 java.util.concurrent
    ? 低级锁定
            ─ synchronized() 阻塞

    ? 低级原语
            ─ Volatile 变量,
              java.util.concurrent.atomic 类
            ─ 考虑非阻塞同步
    ? 数据争用:故意不完全同步
            ─ 避免!
            ─ 甚至 Doug Lea 也不能正确了解
8   | 2004 JavaOneSM Conference | Session TS-2331
同步的叁个方面

    ? 原子性
            ─ 锁定以获得互斥

    ? 可见性
            ─ 确保一个线程中对象域的更改在其它线程中可
              见
    ? 顺序性
            ─ 确保对语句执行的顺序不会感到惊奇




9   | 2004 JavaOneSM Conference | Session TS-2331
不要试图太聪明

     ? 人们担心同步的成本
             ─ 尝试不使用同步,设计模式在线程之间进行通信
                    ─ 锁定、 volatile 或其它并发抽象

     ? 几乎不可能正确执行
             ─ 无同步的线程内通信是不直观的




10   | 2004 JavaOneSM Conference | Session TS-2331
测验时间


                                                     x = y = 0

                                                      启动线程
                   线程 1                                              线程 2
                                  x = 1                          y = 1


                                  j = y                          i = x


                           能得到 i = 0 和 j = 0 这样的结果么 ?


11   | 2004 JavaOneSM Conference | Session TS-2331
答案:是!


                                                     x = y = 0

                                                      启动线程
                   线程 1                                              线程 2
                                  x = 1                          y = 1


                                  j = y                          i = x


                                             如何得到 i=0 和 j=0?


12   | 2004 JavaOneSM Conference | Session TS-2331
这是如何发生的 ?

     ? 编译器可以对语句重新排序
             ─ 或者保持寄存器中的值
     ? 处理器可以对其重新排序
     ? 在多处理器中,值不能在全局存储器中同步
     ? 内存模型的设计旨在允许强力优化
             ─ 包括尚未实现的优化
     ? 对性能有益
             ─ 对有关不充分的同步代码的直觉不利



13   | 2004 JavaOneSM Conference | Session TS-2331
正确性和优化

     ? 根据你认为系统必须按照的顺序而设计的巧妙代
           码在 Java 语言中几乎总是错误的
     ? Dekker 的算法(第一个正确锁定实现)要求此
           顺序
             ─ 在 Java 语言中不能运行,使用提供的锁定
     ? 必须使用同步来加强可见性和顺序性
             ─ 以及互斥
             ─ 如果你正确使用同步,那么你不会看到重新排序




14   | 2004 JavaOneSM Conference | Session TS-2331
同步操作
      (近似)

     // block until obtain lock
     synchronized(anObject) {
         // get main memory value of field1 and field2
         int x = anObject.field1;
         int y = anObject.field2;
         anObject.field3 = x+y;
     // commit value of field3 to main memory
     }
     // release lock
     moreCode();


15   | 2004 JavaOneSM Conference | Session TS-2331
操作何时对其它线程可见 ?

                                                     解除锁定(释放)之前   线程 2
            ref1.x = 1                               的一切

                  lock M                                      lock M

            glo = ref1                                      ref2 = glo

               unlock M                                      unlock M

                                                            j = ref2.x
 线程 1                          对同一对象的随后锁定
                               (获取)之后的一切
                               都可见

16   | 2004 JavaOneSM Conference | Session TS-2331
释放和获取

     ? 释放之前的所有访问
             ─ 提前排序,并可见
             ─ 匹配获取之后的任意访问
     ? 解除锁定监视器 / 锁定是一种释放
             ─ 由该监视器 / 锁定的下列任何锁定获取




17   | 2004 JavaOneSM Conference | Session TS-2331
排序

     ? Roach motel 排序
             ─ 编译器 / 处理器可将访问移入同步阻塞
             ─ 仅在某些特殊情况下,能将其移出,通常不可见
     ? 某些特殊情况:
             ─ 线程局部对象上的锁是空操作
             ─ 可重入锁是空操作




18   | 2004 JavaOneSM Conference | Session TS-2331
Volatile 域

     ? 如果某个域可同时被多个线程访问,并且访问中至少有
           一个是写
             ─ 将域设置为 volatile
                    ─ 记录
                    ─ 赋予必要的 Java? 虚拟机保证
             ─ 要操作正确则很复杂,但没有 volatile 几乎是不可能的

     ? volatile 做些什么 ?
             ─ 直接向内存读和写
                    ─ 不缓存或保留在寄存器中
             ─ Volatile long 和 double 是原子型的
                    ─ 对非 volatile long 和 double 不适用
             ─ 编译器重新排序 volatile 访问受限制

19   | 2004 JavaOneSM Conference | Session TS-2331
Volatile 释放 / 获取

     ? volatile 写是一种释放
             ─ 由随后读取同一变量获取
     ? 在 volatile 写之前的所有访问
             ─ 在 volatile 读取之后的所有访问之前排序,并且这些
               访问可见




20   | 2004 JavaOneSM Conference | Session TS-2331
Volatile 保证了可见性

     ? stop 必须声明为 volatile
             ─ 否则,编译器可能将其保存在寄存器中


            class Animator implements Runnable {
              private volatile boolean stop = false;
              public void stop() { stop = true; }
              public void run() {
                while (!stop)
                  oneStep();
              }
              private void oneStep() { /*...*/ }
            }

21   | 2004 JavaOneSM Conference | Session TS-2331
Volatile 保证了顺序


     ? 如果线程读取了数据,则 ready 上的释放 / 获取
           保证了可见性和顺序性

     class Future {
        private volatile boolean ready;
        private Object data;
        public Object get() {
           if (!ready)
             return null;      public synchronized
           return data;           void setOnce(Object o) {
           }                        if (ready) throw … ;
                                    data = o;
                                    ready = true;
                                    }
                                }
22   | 2004 JavaOneSM Conference | Session TS-2331
其它获取和释放

     ? 其它操作构成了释放 / 获取对
     ? 启动线程是一种释放
             ─ 由线程的 run 方法获取
     ? 结束线程是一种释放
             ─ 由和结束线程一起的任一线程获取




23   | 2004 JavaOneSM Conference | Session TS-2331
防止数据争用

     ? 攻击者可通过数据争用将对象实例传给其它线程
     ? 可造成不可思议的问题
             ─ 可在某些 JVM 中观察到
             ─ 在旧式 JVM 中,可以看到 String
               对象更改
                    ─ 从 /tmp 更改为 /usr
     ? 如果类的安全性很重要,必须采取措施
     ? 选择:
             ─ 使用同步(即使在构造器中)
             ─ 通过把所有域设置为 final ,使对象不可变

24   | 2004 JavaOneSM Conference | Session TS-2331
不可变的类


     ? 将所有关键域设置为 final
     ? 直到该对象已完全构造好,其它线程才能看到
           对象
     ? JVM 会负责确保该对象被视为不可变
             ─ 即使恶意代码使用数据争用攻击该类




25   | 2004 JavaOneSM Conference | Session TS-2331
Final 域的优化

     ? 新规范允许强力优化 final 域
             ─ 通过同步和未知方法调用提升读 final 域
             ─ 仍保留不可变性


     ? 应该考虑到未来的 JVM 获得性能优势




26   | 2004 JavaOneSM Conference | Session TS-2331
必要时进行同步

     ? 线程交互作用的位置
             ─    需要同步
             ─    可能需要慎重考虑
             ─    可能需要记录
             ─    必要的同步成本不重要
                    ─ 适用于多数应用程序
                    ─ 无须复杂化




27   | 2004 JavaOneSM Conference | Session TS-2331
同步类
     ? 某些类被同步
             ─ Vector 、 Hashtable 、 Stack
             ─ 多数输入 / 输出流
             ─ 不需要的同步开销可以度量
     ? 与集合类对比
             ─ 默认情况下,不同步
             ─ 可以请求同步版本
             ─ 或可使用 java.util.concurrent 版本
               ( Queue 、 ConcurrentMap 实现)
     ? 使用同步类
             ─ 通常不能满足并发交互需要

28   | 2004 JavaOneSM Conference | Session TS-2331
同步的集合并不总能满足需要

     ? 事务(不使用)
             ─ 破坏原子性……
                  ID getID(String name) {
                      ID x = h.get(name);
                      if (x == null) {
                         x = new ID();
                         h.put(name, x);
                      }
                      return x;
                  }

     ? 迭代
             ─ 其它线程在集合中进行迭代运算时,不要修改此集合


29   | 2004 JavaOneSM Conference | Session TS-2331
并发交互

     ? 通常需要整个事务是原子的
             ─ 读取和更新映射
             ─ 将记录写到输出流上
     ? 输出流被同步
             ─ 可以有多个线程试图写入同一输出流
             ─ 每个线程的输出不能确定为交叉存取
             ─ 基本上无用




30   | 2004 JavaOneSM Conference | Session TS-2331
util.concurrent

     ? java.util.concurrent 中的东西很不错,请使用它
     ? ConcurrentHashMap 有一些附加功能可避开
           事务处理的问题
             ─ putIfAbsent
             ─ 并发迭代
     ? CopyOnWrite 类允许并发迭代和无阻塞读
             ─ 修改的成本太高,应尽量少用




31   | 2004 JavaOneSM Conference | Session TS-2331
设计快速代码

     ? 做快之前先做对
     ? 减少同步成本
             ─ 避免在线程间共享可变对象
             ─ 避免旧集合类( Vector 、 Hashtable )
             ─ 使用块 I/O (或者,甚至更好, java.nio 类)

     ? 使用 java.util.concurrent 类
             ─ 为速度、可扩展性和正确性而设计

     ? 避免锁争用
             ─ 减少锁定范围
             ─ 减少锁定时间
32   | 2004 JavaOneSM Conference | Session TS-2331
故障所在

     ? 考虑内存屏障
             ─ 没有什么可提供内存屏障的影响
     ? 最初的双重检查用法
             ─ AKA 多线程迟缓初始化
             ─ 任何非同步的非 volatile 型读 / 写引用
     ? 根据可见性的睡眠
     ? 对于数据争用的因果智能推断



33   | 2004 JavaOneSM Conference | Session TS-2331
线程局部对象的同步

     ? 线程局部对象的同步
             ─    (仅由单一线程访问的对象)
             ─    没有语义或含义
             ─    编译器可以删除
             ─    也可以删除可重入同步
                    ─ 例如,从同一对象的其它同步方法中调用某个同步的
                      方法
     ? 这是人们暂时讨论的一种优化
             ─ 不确定现在还是否有人使用




34   | 2004 JavaOneSM Conference | Session TS-2331
线程安全的迟缓初始化

     ? 要对许多线程共享的对象执行迟缓初始化
     ? 在初始化对象后,不要补偿同步
     ? 标准的双重检查锁定无法运行
             ─ 使用检查的域 volatile 来修复
     ? 如果两个线程可能同时访问某个域,其中一个
           写入
             ─ 域必须是 volatile




35   | 2004 JavaOneSM Conference | Session TS-2331
结尾

     ? 同步操作的成本非常高
             ─ 但必要的同步成本很少
     ? 线程交互需要慎重考虑
             ─ 不要太聪明
             ─ 没有必要将重新排序考虑的很难
                    ─ 程序中无数据争用,
                     无可见的重新排序
     ? 需要内部线程通信……



36   | 2004 JavaOneSM Conference | Session TS-2331
结尾—通信

     ? 线程间的通信
             ─ 要求两个线程通过同步进行交互
     ? JSR-133 和 166 提供了通信的新机制
             ─ 高级并发性框架
             ─ Volatile 域
             ─ Final 域




37   | 2004 JavaOneSM Conference | Session TS-2331
问与答

38   | 2004 JavaOneSM Conference | Session TS-2331
最新 Java? 技术内存
        模型                                           java.sun.com/javaone/sf




       Jeremy Manson 和 William Pugh
       马里兰大学
       http://www.cs.umd.edu/~pugh

39   | 2004 JavaOneSM Conference | Session TS-2331

More Related Content

What's hot (10)

Btrace intro(撒迦)
Btrace intro(撒迦)Btrace intro(撒迦)
Btrace intro(撒迦)
ykdsg
?
闯痴惭内容管理和垃圾回收
闯痴惭内容管理和垃圾回收闯痴惭内容管理和垃圾回收
闯痴惭内容管理和垃圾回收
Tony Deng
?
Inside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutor
Inside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutorInside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutor
Inside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutor
Ady Liu
?
Free rtos workshop1@nuu
Free rtos workshop1@nuuFree rtos workshop1@nuu
Free rtos workshop1@nuu
紀榮 陳
?
Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)
Kris Mok
?
闯补惫补并发编程实践
闯补惫补并发编程实践闯补惫补并发编程实践
闯补惫补并发编程实践
sharewind
?
闯惫尘内存管理基础
闯惫尘内存管理基础闯惫尘内存管理基础
闯惫尘内存管理基础
wang hongjiang
?
滨翱厂入门分享
滨翱厂入门分享滨翱厂入门分享
滨翱厂入门分享
zenyuhao
?
闯补惫补并发编程培训
闯补惫补并发编程培训闯补惫补并发编程培训
闯补惫补并发编程培训
longhao
?
Btrace intro(撒迦)
Btrace intro(撒迦)Btrace intro(撒迦)
Btrace intro(撒迦)
ykdsg
?
闯痴惭内容管理和垃圾回收
闯痴惭内容管理和垃圾回收闯痴惭内容管理和垃圾回收
闯痴惭内容管理和垃圾回收
Tony Deng
?
Inside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutor
Inside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutorInside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutor
Inside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutor
Ady Liu
?
Free rtos workshop1@nuu
Free rtos workshop1@nuuFree rtos workshop1@nuu
Free rtos workshop1@nuu
紀榮 陳
?
Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)
Kris Mok
?
闯补惫补并发编程实践
闯补惫补并发编程实践闯补惫补并发编程实践
闯补惫补并发编程实践
sharewind
?
闯惫尘内存管理基础
闯惫尘内存管理基础闯惫尘内存管理基础
闯惫尘内存管理基础
wang hongjiang
?
滨翱厂入门分享
滨翱厂入门分享滨翱厂入门分享
滨翱厂入门分享
zenyuhao
?
闯补惫补并发编程培训
闯补惫补并发编程培训闯补惫补并发编程培训
闯补惫补并发编程培训
longhao
?

Similar to 最新闯补惫补技术内存模型 (20)

Notes of jcip
Notes of jcipNotes of jcip
Notes of jcip
Dai Jun
?
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Justin Lin
?
千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7
Justin Lin
?
主库自动切换 V2.0
主库自动切换 V2.0主库自动切换 V2.0
主库自动切换 V2.0
jinqing zhu
?
惭测厂蚕尝自动切换设计与实现
惭测厂蚕尝自动切换设计与实现惭测厂蚕尝自动切换设计与实现
惭测厂蚕尝自动切换设计与实现
orczhou
?
如何在 Java App 中導入 Scala
如何在 Java App 中導入 Scala如何在 Java App 中導入 Scala
如何在 Java App 中導入 Scala
javatwo2011
?
闯补惫补并发核心编程
闯补惫补并发核心编程闯补惫补并发核心编程
闯补惫补并发核心编程
wavefly
?
淘宝主备数据库自动切换
淘宝主备数据库自动切换淘宝主备数据库自动切换
淘宝主备数据库自动切换
mysqlops
?
Ecmascript
EcmascriptEcmascript
Ecmascript
jay li
?
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
wang hongjiang
?
潜力无限的编程语言闯补惫补蝉肠谤颈辫迟
潜力无限的编程语言闯补惫补蝉肠谤颈辫迟潜力无限的编程语言闯补惫补蝉肠谤颈辫迟
潜力无限的编程语言闯补惫补蝉肠谤颈辫迟
jay li
?
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Justin Lin
?
Enqueue Lock介绍.ppt
Enqueue Lock介绍.pptEnqueue Lock介绍.ppt
Enqueue Lock介绍.ppt
james tong
?
3. 流程語法與函式
3. 流程語法與函式3. 流程語法與函式
3. 流程語法與函式
Justin Lin
?
2014暑期訓練之Linux kernel power
2014暑期訓練之Linux kernel power2014暑期訓練之Linux kernel power
2014暑期訓練之Linux kernel power
冠宇 陳
?
Chapter2
Chapter2  Chapter2
Chapter2
Fang-Ling Lin
?
lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用
hugo
?
Track2 -刘继伟--openstack in gamewave
Track2 -刘继伟--openstack in gamewaveTrack2 -刘继伟--openstack in gamewave
Track2 -刘继伟--openstack in gamewave
OpenCity Community
?
谤别诲颈蝉实现分布式锁.辫辫迟虫
谤别诲颈蝉实现分布式锁.辫辫迟虫谤别诲颈蝉实现分布式锁.辫辫迟虫
谤别诲颈蝉实现分布式锁.辫辫迟虫
rocx1231
?
2, object oriented programming
2, object oriented programming2, object oriented programming
2, object oriented programming
ted-xu
?
Notes of jcip
Notes of jcipNotes of jcip
Notes of jcip
Dai Jun
?
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Justin Lin
?
千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7
Justin Lin
?
主库自动切换 V2.0
主库自动切换 V2.0主库自动切换 V2.0
主库自动切换 V2.0
jinqing zhu
?
惭测厂蚕尝自动切换设计与实现
惭测厂蚕尝自动切换设计与实现惭测厂蚕尝自动切换设计与实现
惭测厂蚕尝自动切换设计与实现
orczhou
?
如何在 Java App 中導入 Scala
如何在 Java App 中導入 Scala如何在 Java App 中導入 Scala
如何在 Java App 中導入 Scala
javatwo2011
?
闯补惫补并发核心编程
闯补惫补并发核心编程闯补惫补并发核心编程
闯补惫补并发核心编程
wavefly
?
淘宝主备数据库自动切换
淘宝主备数据库自动切换淘宝主备数据库自动切换
淘宝主备数据库自动切换
mysqlops
?
Ecmascript
EcmascriptEcmascript
Ecmascript
jay li
?
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
wang hongjiang
?
潜力无限的编程语言闯补惫补蝉肠谤颈辫迟
潜力无限的编程语言闯补惫补蝉肠谤颈辫迟潜力无限的编程语言闯补惫补蝉肠谤颈辫迟
潜力无限的编程语言闯补惫补蝉肠谤颈辫迟
jay li
?
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Justin Lin
?
Enqueue Lock介绍.ppt
Enqueue Lock介绍.pptEnqueue Lock介绍.ppt
Enqueue Lock介绍.ppt
james tong
?
3. 流程語法與函式
3. 流程語法與函式3. 流程語法與函式
3. 流程語法與函式
Justin Lin
?
2014暑期訓練之Linux kernel power
2014暑期訓練之Linux kernel power2014暑期訓練之Linux kernel power
2014暑期訓練之Linux kernel power
冠宇 陳
?
lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用
hugo
?
Track2 -刘继伟--openstack in gamewave
Track2 -刘继伟--openstack in gamewaveTrack2 -刘继伟--openstack in gamewave
Track2 -刘继伟--openstack in gamewave
OpenCity Community
?
谤别诲颈蝉实现分布式锁.辫辫迟虫
谤别诲颈蝉实现分布式锁.辫辫迟虫谤别诲颈蝉实现分布式锁.辫辫迟虫
谤别诲颈蝉实现分布式锁.辫辫迟虫
rocx1231
?
2, object oriented programming
2, object oriented programming2, object oriented programming
2, object oriented programming
ted-xu
?

More from yiditushe (20)

厂辫谤颈苍驳入门纲要
厂辫谤颈苍驳入门纲要厂辫谤颈苍驳入门纲要
厂辫谤颈苍驳入门纲要
yiditushe
?
J Bpm4 1中文用户手册
J Bpm4 1中文用户手册J Bpm4 1中文用户手册
J Bpm4 1中文用户手册
yiditushe
?
性能测试实践2
性能测试实践2性能测试实践2
性能测试实践2
yiditushe
?
性能测试实践1
性能测试实践1性能测试实践1
性能测试实践1
yiditushe
?
性能测试技术
性能测试技术性能测试技术
性能测试技术
yiditushe
?
Load runner测试技术
Load runner测试技术Load runner测试技术
Load runner测试技术
yiditushe
?
J2 ee性能测试
J2 ee性能测试J2 ee性能测试
J2 ee性能测试
yiditushe
?
面向对象的闯蝉培训
面向对象的闯蝉培训面向对象的闯蝉培训
面向对象的闯蝉培训
yiditushe
?
贵濒别虫3中文教程
贵濒别虫3中文教程贵濒别虫3中文教程
贵濒别虫3中文教程
yiditushe
?
开放源代码的全文检索尝耻肠别苍别
开放源代码的全文检索尝耻肠别苍别开放源代码的全文检索尝耻肠别苍别
开放源代码的全文检索尝耻肠别苍别
yiditushe
?
基于分词索引的全文检索技术介绍
基于分词索引的全文检索技术介绍基于分词索引的全文检索技术介绍
基于分词索引的全文检索技术介绍
yiditushe
?
Lucene In Action
Lucene In ActionLucene In Action
Lucene In Action
yiditushe
?
Lucene2 4学习笔记1
Lucene2 4学习笔记1Lucene2 4学习笔记1
Lucene2 4学习笔记1
yiditushe
?
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
yiditushe
?
Lucene 3[1] 0 原理与代码分析
Lucene 3[1] 0 原理与代码分析Lucene 3[1] 0 原理与代码分析
Lucene 3[1] 0 原理与代码分析
yiditushe
?
7 面向对象设计原则
7 面向对象设计原则7 面向对象设计原则
7 面向对象设计原则
yiditushe
?
10 团队开发
10  团队开发10  团队开发
10 团队开发
yiditushe
?
9 对象持久化与数据建模
9  对象持久化与数据建模9  对象持久化与数据建模
9 对象持久化与数据建模
yiditushe
?
8 Uml构架建模
8  Uml构架建模8  Uml构架建模
8 Uml构架建模
yiditushe
?
厂辫谤颈苍驳入门纲要
厂辫谤颈苍驳入门纲要厂辫谤颈苍驳入门纲要
厂辫谤颈苍驳入门纲要
yiditushe
?
J Bpm4 1中文用户手册
J Bpm4 1中文用户手册J Bpm4 1中文用户手册
J Bpm4 1中文用户手册
yiditushe
?
性能测试实践2
性能测试实践2性能测试实践2
性能测试实践2
yiditushe
?
性能测试实践1
性能测试实践1性能测试实践1
性能测试实践1
yiditushe
?
性能测试技术
性能测试技术性能测试技术
性能测试技术
yiditushe
?
Load runner测试技术
Load runner测试技术Load runner测试技术
Load runner测试技术
yiditushe
?
J2 ee性能测试
J2 ee性能测试J2 ee性能测试
J2 ee性能测试
yiditushe
?
面向对象的闯蝉培训
面向对象的闯蝉培训面向对象的闯蝉培训
面向对象的闯蝉培训
yiditushe
?
贵濒别虫3中文教程
贵濒别虫3中文教程贵濒别虫3中文教程
贵濒别虫3中文教程
yiditushe
?
开放源代码的全文检索尝耻肠别苍别
开放源代码的全文检索尝耻肠别苍别开放源代码的全文检索尝耻肠别苍别
开放源代码的全文检索尝耻肠别苍别
yiditushe
?
基于分词索引的全文检索技术介绍
基于分词索引的全文检索技术介绍基于分词索引的全文检索技术介绍
基于分词索引的全文检索技术介绍
yiditushe
?
Lucene In Action
Lucene In ActionLucene In Action
Lucene In Action
yiditushe
?
Lucene2 4学习笔记1
Lucene2 4学习笔记1Lucene2 4学习笔记1
Lucene2 4学习笔记1
yiditushe
?
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
yiditushe
?
Lucene 3[1] 0 原理与代码分析
Lucene 3[1] 0 原理与代码分析Lucene 3[1] 0 原理与代码分析
Lucene 3[1] 0 原理与代码分析
yiditushe
?
7 面向对象设计原则
7 面向对象设计原则7 面向对象设计原则
7 面向对象设计原则
yiditushe
?
10 团队开发
10  团队开发10  团队开发
10 团队开发
yiditushe
?
9 对象持久化与数据建模
9  对象持久化与数据建模9  对象持久化与数据建模
9 对象持久化与数据建模
yiditushe
?
8 Uml构架建模
8  Uml构架建模8  Uml构架建模
8 Uml构架建模
yiditushe
?

最新闯补惫补技术内存模型

  • 1. 最新 Java? 技术内存 模型 java.sun.com/javaone/sf Jeremy Manson 和 William Pugh 马里兰大学 http://www.cs.umd.edu/~pugh 1 | 2004 JavaOneSM Conference | Session TS-2331
  • 2. 听众 ? 假设你熟悉基于 Java? 技术的线程(“ Java? 线程”)的基础知识 ─ 创建、启动和加入线程 ─ 同步 ─ wait 和 notifyAll 2 | 2004 JavaOneSM Conference | Session TS-2331
  • 3. Java? 线程规范 ? 修订为 JSR-133 的一部分 ? 属于以下规范中的一部分 ─ 最新 Java? 语言规范 ─ 最新虚拟机规范 ? 今天在此讨论是 JDK? 1.5 版本中的功能 ─ 不是所有这些功能都能保证在以前版本中运行 ─ 突破以前的线程规范 ─ 禁止许多 Java? 虚拟机执行优化 3 | 2004 JavaOneSM Conference | Session TS-2331
  • 4. 多线程系统中的安全问题 ? 不要保留许多直觉假设 ? 某些广泛使用的习惯用法并不安全 ─ 最初的双重检查锁定用法 ─ 检查用于线程结束的 non-volatile 标志 ? 不能使用测试来检查错误 ─ 有些异常情况仅在某些平台上出现 ─ 例如,多处理器 ─ 异常情况很少并且不重复地出现 4 | 2004 JavaOneSM Conference | Session TS-2331
  • 5. 修订线程规范 ? Java? 线程规范已历经重大修订 ─ 多数修订是为适当地规范现有行为 ─ 但行为方面有少数更改 ? 目标 ─ 清晰并且易于理解 ─ 培植可靠的多线程代码 ─ 可供高性能的 Java? 虚拟机使用 ? 已影响 Java? 虚拟机 ─ 以及已编写出的较差的现有代码 ─ 包括 Sun 的 JDK 部分 5 | 2004 JavaOneSM Conference | Session TS-2331
  • 6. 本次演讲…… ? 用 Java? 语言描述构建同步阻塞和并发程序 ─ 语言原语和 util.concurrent 抽象 ? 说明正确同步化代码的意义 ? 尽力使你确信,对于不同步代码的智能推断几 乎肯定可以是错误的 ─ 高效和可靠的程序不需要 6 | 2004 JavaOneSM Conference | Session TS-2331
  • 7. 本次演讲…… ? 我们将主要讨论 ─ 同步方法和阻塞 ─ Volatile 域 ? 同一原则适用于 JSR-166 锁定和原子性操作 ? 还将讨论 final 域和不可变性 7 | 2004 JavaOneSM Conference | Session TS-2331
  • 8. 分类学 ? 高级并发抽象 ─ JSR-166 和 java.util.concurrent ? 低级锁定 ─ synchronized() 阻塞 ? 低级原语 ─ Volatile 变量, java.util.concurrent.atomic 类 ─ 考虑非阻塞同步 ? 数据争用:故意不完全同步 ─ 避免! ─ 甚至 Doug Lea 也不能正确了解 8 | 2004 JavaOneSM Conference | Session TS-2331
  • 9. 同步的叁个方面 ? 原子性 ─ 锁定以获得互斥 ? 可见性 ─ 确保一个线程中对象域的更改在其它线程中可 见 ? 顺序性 ─ 确保对语句执行的顺序不会感到惊奇 9 | 2004 JavaOneSM Conference | Session TS-2331
  • 10. 不要试图太聪明 ? 人们担心同步的成本 ─ 尝试不使用同步,设计模式在线程之间进行通信 ─ 锁定、 volatile 或其它并发抽象 ? 几乎不可能正确执行 ─ 无同步的线程内通信是不直观的 10 | 2004 JavaOneSM Conference | Session TS-2331
  • 11. 测验时间 x = y = 0 启动线程 线程 1 线程 2 x = 1 y = 1 j = y i = x 能得到 i = 0 和 j = 0 这样的结果么 ? 11 | 2004 JavaOneSM Conference | Session TS-2331
  • 12. 答案:是! x = y = 0 启动线程 线程 1 线程 2 x = 1 y = 1 j = y i = x 如何得到 i=0 和 j=0? 12 | 2004 JavaOneSM Conference | Session TS-2331
  • 13. 这是如何发生的 ? ? 编译器可以对语句重新排序 ─ 或者保持寄存器中的值 ? 处理器可以对其重新排序 ? 在多处理器中,值不能在全局存储器中同步 ? 内存模型的设计旨在允许强力优化 ─ 包括尚未实现的优化 ? 对性能有益 ─ 对有关不充分的同步代码的直觉不利 13 | 2004 JavaOneSM Conference | Session TS-2331
  • 14. 正确性和优化 ? 根据你认为系统必须按照的顺序而设计的巧妙代 码在 Java 语言中几乎总是错误的 ? Dekker 的算法(第一个正确锁定实现)要求此 顺序 ─ 在 Java 语言中不能运行,使用提供的锁定 ? 必须使用同步来加强可见性和顺序性 ─ 以及互斥 ─ 如果你正确使用同步,那么你不会看到重新排序 14 | 2004 JavaOneSM Conference | Session TS-2331
  • 15. 同步操作 (近似) // block until obtain lock synchronized(anObject) { // get main memory value of field1 and field2 int x = anObject.field1; int y = anObject.field2; anObject.field3 = x+y; // commit value of field3 to main memory } // release lock moreCode(); 15 | 2004 JavaOneSM Conference | Session TS-2331
  • 16. 操作何时对其它线程可见 ? 解除锁定(释放)之前 线程 2 ref1.x = 1 的一切 lock M lock M glo = ref1 ref2 = glo unlock M unlock M j = ref2.x 线程 1 对同一对象的随后锁定 (获取)之后的一切 都可见 16 | 2004 JavaOneSM Conference | Session TS-2331
  • 17. 释放和获取 ? 释放之前的所有访问 ─ 提前排序,并可见 ─ 匹配获取之后的任意访问 ? 解除锁定监视器 / 锁定是一种释放 ─ 由该监视器 / 锁定的下列任何锁定获取 17 | 2004 JavaOneSM Conference | Session TS-2331
  • 18. 排序 ? Roach motel 排序 ─ 编译器 / 处理器可将访问移入同步阻塞 ─ 仅在某些特殊情况下,能将其移出,通常不可见 ? 某些特殊情况: ─ 线程局部对象上的锁是空操作 ─ 可重入锁是空操作 18 | 2004 JavaOneSM Conference | Session TS-2331
  • 19. Volatile 域 ? 如果某个域可同时被多个线程访问,并且访问中至少有 一个是写 ─ 将域设置为 volatile ─ 记录 ─ 赋予必要的 Java? 虚拟机保证 ─ 要操作正确则很复杂,但没有 volatile 几乎是不可能的 ? volatile 做些什么 ? ─ 直接向内存读和写 ─ 不缓存或保留在寄存器中 ─ Volatile long 和 double 是原子型的 ─ 对非 volatile long 和 double 不适用 ─ 编译器重新排序 volatile 访问受限制 19 | 2004 JavaOneSM Conference | Session TS-2331
  • 20. Volatile 释放 / 获取 ? volatile 写是一种释放 ─ 由随后读取同一变量获取 ? 在 volatile 写之前的所有访问 ─ 在 volatile 读取之后的所有访问之前排序,并且这些 访问可见 20 | 2004 JavaOneSM Conference | Session TS-2331
  • 21. Volatile 保证了可见性 ? stop 必须声明为 volatile ─ 否则,编译器可能将其保存在寄存器中 class Animator implements Runnable { private volatile boolean stop = false; public void stop() { stop = true; } public void run() { while (!stop) oneStep(); } private void oneStep() { /*...*/ } } 21 | 2004 JavaOneSM Conference | Session TS-2331
  • 22. Volatile 保证了顺序 ? 如果线程读取了数据,则 ready 上的释放 / 获取 保证了可见性和顺序性 class Future { private volatile boolean ready; private Object data; public Object get() { if (!ready) return null; public synchronized return data; void setOnce(Object o) { } if (ready) throw … ; data = o; ready = true; } } 22 | 2004 JavaOneSM Conference | Session TS-2331
  • 23. 其它获取和释放 ? 其它操作构成了释放 / 获取对 ? 启动线程是一种释放 ─ 由线程的 run 方法获取 ? 结束线程是一种释放 ─ 由和结束线程一起的任一线程获取 23 | 2004 JavaOneSM Conference | Session TS-2331
  • 24. 防止数据争用 ? 攻击者可通过数据争用将对象实例传给其它线程 ? 可造成不可思议的问题 ─ 可在某些 JVM 中观察到 ─ 在旧式 JVM 中,可以看到 String 对象更改 ─ 从 /tmp 更改为 /usr ? 如果类的安全性很重要,必须采取措施 ? 选择: ─ 使用同步(即使在构造器中) ─ 通过把所有域设置为 final ,使对象不可变 24 | 2004 JavaOneSM Conference | Session TS-2331
  • 25. 不可变的类 ? 将所有关键域设置为 final ? 直到该对象已完全构造好,其它线程才能看到 对象 ? JVM 会负责确保该对象被视为不可变 ─ 即使恶意代码使用数据争用攻击该类 25 | 2004 JavaOneSM Conference | Session TS-2331
  • 26. Final 域的优化 ? 新规范允许强力优化 final 域 ─ 通过同步和未知方法调用提升读 final 域 ─ 仍保留不可变性 ? 应该考虑到未来的 JVM 获得性能优势 26 | 2004 JavaOneSM Conference | Session TS-2331
  • 27. 必要时进行同步 ? 线程交互作用的位置 ─ 需要同步 ─ 可能需要慎重考虑 ─ 可能需要记录 ─ 必要的同步成本不重要 ─ 适用于多数应用程序 ─ 无须复杂化 27 | 2004 JavaOneSM Conference | Session TS-2331
  • 28. 同步类 ? 某些类被同步 ─ Vector 、 Hashtable 、 Stack ─ 多数输入 / 输出流 ─ 不需要的同步开销可以度量 ? 与集合类对比 ─ 默认情况下,不同步 ─ 可以请求同步版本 ─ 或可使用 java.util.concurrent 版本 ( Queue 、 ConcurrentMap 实现) ? 使用同步类 ─ 通常不能满足并发交互需要 28 | 2004 JavaOneSM Conference | Session TS-2331
  • 29. 同步的集合并不总能满足需要 ? 事务(不使用) ─ 破坏原子性…… ID getID(String name) { ID x = h.get(name); if (x == null) { x = new ID(); h.put(name, x); } return x; } ? 迭代 ─ 其它线程在集合中进行迭代运算时,不要修改此集合 29 | 2004 JavaOneSM Conference | Session TS-2331
  • 30. 并发交互 ? 通常需要整个事务是原子的 ─ 读取和更新映射 ─ 将记录写到输出流上 ? 输出流被同步 ─ 可以有多个线程试图写入同一输出流 ─ 每个线程的输出不能确定为交叉存取 ─ 基本上无用 30 | 2004 JavaOneSM Conference | Session TS-2331
  • 31. util.concurrent ? java.util.concurrent 中的东西很不错,请使用它 ? ConcurrentHashMap 有一些附加功能可避开 事务处理的问题 ─ putIfAbsent ─ 并发迭代 ? CopyOnWrite 类允许并发迭代和无阻塞读 ─ 修改的成本太高,应尽量少用 31 | 2004 JavaOneSM Conference | Session TS-2331
  • 32. 设计快速代码 ? 做快之前先做对 ? 减少同步成本 ─ 避免在线程间共享可变对象 ─ 避免旧集合类( Vector 、 Hashtable ) ─ 使用块 I/O (或者,甚至更好, java.nio 类) ? 使用 java.util.concurrent 类 ─ 为速度、可扩展性和正确性而设计 ? 避免锁争用 ─ 减少锁定范围 ─ 减少锁定时间 32 | 2004 JavaOneSM Conference | Session TS-2331
  • 33. 故障所在 ? 考虑内存屏障 ─ 没有什么可提供内存屏障的影响 ? 最初的双重检查用法 ─ AKA 多线程迟缓初始化 ─ 任何非同步的非 volatile 型读 / 写引用 ? 根据可见性的睡眠 ? 对于数据争用的因果智能推断 33 | 2004 JavaOneSM Conference | Session TS-2331
  • 34. 线程局部对象的同步 ? 线程局部对象的同步 ─ (仅由单一线程访问的对象) ─ 没有语义或含义 ─ 编译器可以删除 ─ 也可以删除可重入同步 ─ 例如,从同一对象的其它同步方法中调用某个同步的 方法 ? 这是人们暂时讨论的一种优化 ─ 不确定现在还是否有人使用 34 | 2004 JavaOneSM Conference | Session TS-2331
  • 35. 线程安全的迟缓初始化 ? 要对许多线程共享的对象执行迟缓初始化 ? 在初始化对象后,不要补偿同步 ? 标准的双重检查锁定无法运行 ─ 使用检查的域 volatile 来修复 ? 如果两个线程可能同时访问某个域,其中一个 写入 ─ 域必须是 volatile 35 | 2004 JavaOneSM Conference | Session TS-2331
  • 36. 结尾 ? 同步操作的成本非常高 ─ 但必要的同步成本很少 ? 线程交互需要慎重考虑 ─ 不要太聪明 ─ 没有必要将重新排序考虑的很难 ─ 程序中无数据争用, 无可见的重新排序 ? 需要内部线程通信…… 36 | 2004 JavaOneSM Conference | Session TS-2331
  • 37. 结尾—通信 ? 线程间的通信 ─ 要求两个线程通过同步进行交互 ? JSR-133 和 166 提供了通信的新机制 ─ 高级并发性框架 ─ Volatile 域 ─ Final 域 37 | 2004 JavaOneSM Conference | Session TS-2331
  • 38. 问与答 38 | 2004 JavaOneSM Conference | Session TS-2331
  • 39. 最新 Java? 技术内存 模型 java.sun.com/javaone/sf Jeremy Manson 和 William Pugh 马里兰大学 http://www.cs.umd.edu/~pugh 39 | 2004 JavaOneSM Conference | Session TS-2331