JAVA高效并发

2019-06-27  本文已影响0人  cjxll
主内存与工作内存

java内存模型规定所有的变量(实例字段,静态字段,数组元素)都存储在主内存中。每条线程有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝。线程对变量的所有操作都必须在工作内存中完成,不能直接读写主内存。

内存间交互操作

java定义了8中操作来完成主内存与工作内存的交互

  1. lock: 锁定,作用于主内存的变量把一个变量标志为一条线程独占
  2. unlock:解锁,作用与主内存的变量,把标志为锁定的变量释放出来
  3. read:读取,作用于主内存变量,把一个变量的值从主内存传输到工作内存
  4. load:载入,作用于工作内存,把read到的值放入工作内存的变量副本中
  5. use:使用,作用于工作内存,把工作内存的变量传递给执行引擎
  6. assign:赋值,作用与工作内存,把执行引擎接收到的值赋值给工作内存的变量
  7. store:作用于工作内存,把工作内存中的一个变量传递到主内存
  8. write:作用于主内存,把store操作中的变量值方放到主内存的变量中

valatile

java 虚拟机提供的轻量级的同步机制,

long,double型变量的特殊规则

允许JVM将没有被valatile修饰的64位数据的读写操作划分为2次32位的操作来进行

先行先发生原则,如果2个操作之间无法从下列规则推导出来,则JVM可以对他们随意的排序

  1. 程序次序规则
  2. 管程锁定规则
  3. valatile变量规则
  4. 线程启动规则
  5. 线程停止规则
  6. 线程终止规则
  7. 线程中断规则
  8. 对象终结规则
  9. 传递性

java与线程

使用抢占式线程调度

线程的状态

java操作共享数据分为5类

  1. 不可变,final关键字修饰
  2. 绝对线程安全,不管运行时环境如何,调用者都不需要额外的同步措施
  3. 相对线程安全,我们通常意义上所讲的线程安全,对象单独操作时线程安全的
  4. 线程兼容,值对象本身并不是线程安全的,但可以通过在调用端正确地使用同步手段在并发环境中可以安全的使用
  5. 线程对立,指无论调用端是否采取了同步措施,都无法再多线程环境中并发使用

线程安全的实现方法

  1. 互斥同步:同步是指保证共享数据在同一时刻只被一个(或一些,使用信号量的时候)线程使用。互斥是实现同步的一种手段,临界区,互斥量和信号量等方式。最基本的互斥同步手段就是synchronized关键字,执行monitorenter指令时先尝试获取对象的锁,如果没被锁定,或当前线程以及有该锁,则锁的计数器+1,相应的执行monitorexit指令时-1,当计数器为0时,锁就释放。
    JUC包下的ReentrantLock与synchronized区别:
  1. 非阻塞同步:基于冲突检测的乐观锁并发策略,就是先进行操作,如果没有其他线程争用共享数据,那就操作成功,如果有,产生了冲突,那就采取补偿措施(不断重试),CAS依赖底层指令实现,存在“ABA"逻辑漏洞问题。
  2. 无同步方案
    可重入代码:不依赖存储在堆上的数据和公用资源,如果一个方法,他的返回结果是可预测的,只要相同的数据,就都能返回相同的结果,那它就满足可重入性的要求。
    线程本地存储:将共享数据的可见范围限制在一个线程内,每一Thread对象中都有一个ThreaLocalMap对象,存储了一组以ThreadLocal.threadLocalHashCode为键,以本地线程变量为值的K-V值对。

锁优化

上一篇 下一篇

猜你喜欢

热点阅读