zoukankan      html  css  js  c++  java
  • Java并发编程的艺术 记录(三)

    Java内存模型

      并发编程的两个关键问题:

        1.线程之间如何通讯。

        2.线程间如何同步。

      两种方式:共享内存和消息传递。

      Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式进行,整个通信过程对程序员完全透明。

      实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享。Java线程之间的通信由Java内存模型:JMM控制。

      JMM通过控制主内存与每个线程的本地内存之间的交互,来为Java程序员提供内存可见性保证 。

      重排序分3种类型:
        1)编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
        2)指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-LevelParallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
        3)内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行 。

      对于处理器重排序,JMM的处理器重排序规则会要求Java编译器在生成指令序列时,插入特定类型的内存屏障(Memory Barriers,Intel称之为Memory Fence)指令,通过内存屏障指令来禁止特定类型的处理器重排序 。

      happens-before规则如下:
        1.·程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
        2.·监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
        3.·volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
        4.·传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。

      顺序一致性,可见性保证。所有的操作按程序的顺序执行,而JMM中临界区内的代码可以重排序。

      volatile写的内存语义如下。
        当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。

      volatile读的内存语义如下。
        当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

      ReentrantLock:有公平锁和非公平锁

      Java线程之间的通信4种方式
        1)A线程写volatile变量,随后B线程读这个volatile变量。
        2)A线程写volatile变量,随后B线程用CAS更新这个volatile变量。
        3)A线程用CAS更新一个volatile变量,随后B线程用CAS更新这个volatile变量。
        4)A线程用CAS更新一个volatile变量,随后B线程读这个volatile变量

  • 相关阅读:
    TCP服务器是否需要心跳包?
    用最简单的函数实现功能:判断一个int数据是否是2的x次幂(不能使用循环)。
    防止程序启动两次的方法CreateMutex()
    WINDOWS操作系统中可以允许最大的线程数
    setsockopt 设置socket 详细用法
    我的结论:DX9不支持非2的次幂尺寸纹理,还得显卡说了算
    D3DX_DEFAULT_NONPOW2
    【解决】Select网络模型问题——奇怪的发送接收问题
    CRC32 简单使用
    .NET开发总结 2010年2月
  • 原文地址:https://www.cnblogs.com/liter7/p/9471196.html
Copyright © 2011-2022 走看看