线程安全及实现原理

2019-01-22  本文已影响0人  FightForFuture
一、基本概念
  1. 锁(重量级锁)是什么?
    每个对象实例都有一个monitor(C++实现), synchronize对象锁,其指针指向的是该对象monitor对象的起始地址。
ObjectMonitor {
_count = 0;          // 被获取之后,count + 1
_owner = NULL;   // 获取到锁的线程
_WaitSet = NULL;   // 线程获取锁失败,会被阻塞,进入_WaitSet等待被唤醒
_EntrySet = NULL;  // 多个线程访问同步块,首先进入_EntrySet
}
  1. 锁的状态
    java对象头包括两部分:
二、线程安全的实现方法
public T get() {};  // 获取ThreadLocal 在当前线程保存的变量副本
public void set(T value) {}; // 设置当前线程中的变量副本
public void remove() {};  // 移除当前线程中变量副本
protected T initialValue() {};

实现方式:每个线程Thread内部都有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,此变量是用来保存变量副本的,当前threadLocal对象为key,value为变量值。

public T get()   {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);  // 返回当前线程ThreadLocal.ThreadLocalMap对象
if (null != map)
{
     ThreadLocalMap.Entry entry = map.getEntry(this);  
     // 注意,key是ThreadLocal对象,而非线程对象。
     if(null != entry)
     {
         return (T)entry.getValue();
     }
     return setInitialValue();
}
}

三、锁优化

JVM首先在当前线程的帧栈中建立一个名为Lock Record 的空间,用于存储锁对象目前的mark word 拷贝。然后,JVM尝试用CAS操作,将锁对象的Mark word更新为指向Lock Record的指针,如果成功了,那么线程就拥有了该对象锁,mark word状态更新为00,表示此对象处于轻量级所状态。

图片2.png
四、synchronize 实现原理

jdk1.6之前,synchronize是典型的互斥同步,然而互斥同步最大的问题就是线程的阻塞与唤醒带来的性能问题,1.6之后jdk团队对锁的各项优化也应用到synchronize上面:
锁升级(不能降级)
无状态锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁

上一篇 下一篇

猜你喜欢

热点阅读