jvm高效并发12 13

1.原子性:一个操作要么执行完,要么不执行。

2.可见性:线程修改数据以后,其他线程应该立马可见。

3.有序性(指令重排 影响多线程)

volatile的作用

        1.当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值(保证可见性)。

        2.保证一定的“有序性”

例如 volatile int i=10;

        线程一: i++;-》》》》》取i,入栈,自增,出栈,写入主存

        线程二:i++;

线程一,读取10并且入栈准备计算,中断,线程二运行修改i=11;(此时通知线程一无效,但是入栈了,线程一无反应)线程一继续运行得11写入   最终结果为11(错误!!!!)

内存间交互操作

             lock   把变量标记为一个线程独占

            unlock  解锁

             read  从主存中读取数据到工作内存

             load  把获取的变量值放入工作内存的变量副本中

             use 把变量的值传递给执行引擎(入栈)

             assign  作用于工作内存的变量,把从执行引擎获取的值赋给工作内存变量

             store把变量值从工作内存传递给主存

             write 作用于主存变量,把store传递的变量赋值给主存变量

 

hanppens-before规则

程序次序规则:一个线程内操作有序。

管程锁定规则:对于同一个锁,unlock先于lock

volatile规则:对于一个被修饰的变量,write先于read

线程启动规则:start()先行发生于此线程的每一个动作

线程终止规则:线程所有操作先行发生于对此线程的终止检测。join(),isAlive()

线程中断规则:对线程的interrupt()方法调用先行发生于被中断线程的代码检测到中断事件的发生

 

对象终结规则:初始化完成先行于finalize()的开始

传递性:

 

 

 

Double Check

private volatile Resource resource;  
public Resource getResource(){  
  if (resource == null){   
    synchronized(this){   
      if (resource==null){  
        resource = new Resource();    
      }     
    }    
  }  
  return resource;  
}  

 

java与线程

线程的实现:1.内核线程 :通过操纵调度器来对线程进行调度,并映射到CPU

                     轻量级线程:内核线程的一种gao高级接口,每个LWP都有一个内核线程支持

                    2.用户线程UT:广义上非内核线程,狭义上线程完全建立在用户线程库上,不需要内核的帮助,优点开销小,确定没有内核支持。所有线程操作都要用户程序自己处理。

                    3.用户线程+LWP混合实现:java中,SUN jdk一个java线程就映射到一个LWP中 windows,linux都是

                                                                               Solaris平台同时支持1:1,n:n,有参数指定

五种线程状态

New

Runable

Waiting

Timed Waiting

Blocked

Terminated

 

线程安全:多个线程访问同一个对象,如果不用考虑运行时环境下的调度和交替执行,也不需要额外的同步或对调用方进行任何协调操作,都可以得到正确的结果。

java中分为:不可变,final修饰,不受多线程影响

                 绝对线程安全,不管运行时环境如何调用者都不需要任何额外的操作同步措施  

                  相对线程安全,对这个对象单独的操作是线程安全的

                    线程兼容,并不安全,可以通过同步手段保证

                    线程对立,无论是否采取tong同步措施,都无法在多线程环境中使用的代码

 

线程安全的实现方法

           1.互斥同步(悲观)   费时,因为线程挂起恢复要在内核态中完成

                      保证共享数据在同一时刻只能被一个(或一些,使用信号量的时候)线程使用,实现互斥同步有临界区、互斥量、信号量synchronized对同一个线程是可重入的。

           2.非阻塞同步(乐观)

                      测试并设置(Test and Set)

                      获取并增加(Fetch and Increment)

                      交换(Swap)

                      比较并交换(CAS)  ABA,循环时间长开销大,只能保证一个共享变量的原子操作

                      加载链接/条件存储(Load Linked/Store-Conditional     LL/SC)

           3.无同步方案

                      可重入代码

                      线程本地存储,限制在一个线程中进行操作

 

锁优化

       自旋锁与自适应自旋
         共享数据的锁定状态只会持续很短的一段时间,阻塞同步开销过大,因此只需要让后面请求锁的线程“稍等一下”
自旋不能代替阻塞,避免了线程切换开销,但是要占用处理器时间,若锁被占用的时间过长,自旋线程只会浪费处理器资源
因此有一定的限度,例如自旋次数默认为10次,没有获得锁,就会挂起线程。可以通过参数修改。现在有自适应自旋。

       锁消除
         指jvm即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的的锁进行消除。锁
消除的主要判定依据来自于逃逸分析的数据支持,如果判断在一段代码中,堆上的所有数据都不会逃逸出去从而被其他线程
访问到,那么就可以把其看做线程栈上的数据看待。

       锁粗化

           一系列连续加锁解锁操作都对同一个对象,甚至在循环体中,没有线程竞争也会有性能损失,因此,直接把锁覆盖到整个操作序列,这样只加锁一次就好。

 

       偏向锁
         在无竞争的情况下把整个同步过程消除掉。这个锁会偏向于第一个获得他的线程,如果该锁没有被其他线程获取,那
持有该锁的线程将永远不需要被同步。

未锁定                            哈希码                                                 分代年龄                             0                                  01

 

当锁对象第一次被线程获取的时候,虚拟机把标志位设为01,即偏向模式,同时,用CAS操作把当前线程的ID记录在MarkWord中    若CAS成功,持有偏向锁的线程每次进入这个锁相关的同步块的时候,虚拟机可以不再进行任何同步操作

当另外一个线程尝试去获取这个锁的时候,偏向模式结束。           根据锁对象目前是否处于被锁定状态,撤销偏向后恢复到未锁定(01)或者轻量级锁定(00),后序同步操作按轻量级锁执行

 

      轻量级锁

         在无竞争的情况下使用CAS操作去消除同步使用的互斥量

         代码进入同步块的时候,如果此同步对象没有被锁定(标志位为01)虚拟机首先将   当前线程的栈帧中建立一个名为Lock Record(锁记录)的空间,用于存储锁对象目前的Mark Word的拷贝(Displaced M W),这时候线程堆栈与对象头的状态如下所示。然后,虚拟机用CAS操作尝试将 对象 的MW更新为指向LR的 指针,

               如果这个更新动作完成了,那么这个线程就拥有了该对象的锁,并且对象MW的标志位转变为“00”表示对象处于轻量级锁定状态下,此时如图所示。

              如果更新失败了。虚拟机首先会检查对象的MW是否指向当前线程的栈帧,如果只说明当前线程已经拥有这个对象的锁,那么直接进入同步块继续执行
                否则说明这个锁对象已经被其他线程抢占了。如果有两个以上的线程争用同一个锁,那么轻量级锁会升级为重量级锁,标志位变为(10)对象MW中存放的就是指向重量级锁的指针,后面等待锁的线程也要进入阻塞状态。

              解锁操作,如果对象的MW仍然指向线程的锁记录,那就用CAS操作把对象当前的MW和线程中复制的Displaced MW替换回来,成功 则同步完成,失败则说明有其他线程尝试过获取该锁,那么在释放锁的同时,唤醒被挂起的线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值