首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java并发机制底层实现原理锁的膨胀过程

Java并发机制底层实现原理锁的膨胀过程

作者头像
须臾之余
发布2020-11-24 10:55:18
3140
发布2020-11-24 10:55:18
举报
文章被收录于专栏:须臾之余须臾之余须臾之余

锁的膨胀过程

预备知识CAS

硬件对并发的支持

在大多数处理器架构(包括IA32和Sparc)中采用的方法是实现一个比较并交换(CAS)指令,CAS包含了3个操作数——内存位置(V),预期原值(A),拟写入的新值(B),当且仅当V == A 时,CAS才会通过原子方式用新值(B)来更新(V)原有的值,无论操作成功与否,都会返回(V)值,且整个过程都是不可打断的,所以CAS是一个原子操作;主要是利用CPU的CAS指令,同时借助JNI来完成Java的非阻塞算法。

模拟CAS操作

public class SimpleCAS {

    private Integer value;

    private synchronized int get(){
        return value;
    }
    private synchronized int compareAndSwap(int a, int b){
        int v = value;
        return v == a ? b : v;
    }
    class CasCounter{
        private SimpleCAS simpleCAS;
        private Integer getValue(){
            return simpleCAS.get();
        }
        private Integer increment(){
            Integer v;
            do {
                v = simpleCAS.get();
            }
            while (v != simpleCAS.compareAndSwap(v,  v + 1));
            return v + 1;
        }
    }
}

预备知识 公平锁&非公平锁

公平锁:第一次加锁的时候,他不会去尝试加锁,他会去看一下我前面有没有人正在排队,如果有人排队,我就先去排队,进入队列后,如果前面那个人是head头结点,他会再次尝试加锁,成功则执行同步代码块,失败则park(真正的排队了); 非公平锁:他首先会在lock方法调用的时候去抢锁,如果失败,则会去看看为啥会失败(锁是不是被人持有了),如果没有人持有,非公平锁则会直接加锁(不会判断是否有人排队),成功则进入同步代码块,失败则进入队列。

流程图

关于队列如何设计和形成的

1、AQS类设计的主要属性

private transient volatile Node head;/队首
private transient volatile Node tail;//队尾
private volatile int state;//锁状态标识

2、Node类的设计

static final class Node {
        volatile Node prev;
        volatile Node next;
        volatile Thread thread;
}

同步器包含了两种节点类型的引用,一个指向头结点,而另外一个指向尾节点,没有成功获取同步状态的线程将会成为节点加入到该队列的尾部。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 预备知识CAS
    • 硬件对并发的支持
      • 模拟CAS操作
      • 预备知识 公平锁&非公平锁
        • 流程图
        • 关于队列如何设计和形成的
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档