(转载)Java CAS 和 synchronized 和 Lock

原文链接:Java CAS 和 synchronized 和 Lock - CSDN博客

CAS 机制

适用场景:乐观认为并发不高,不需要阻塞,可以不上锁。 

特点:不断比较更新,直到成功。

缺点:高并发cpu压力大;ABA问题。

ABA问题: 

CAS机制生效的前提是,取出内存中某时刻的数据,而在下时刻比较并替换。 

如果在比较之前,数据发生了变化,例如:A->B->A,即A变为B然后又变化A,那么这个数据还是发生了变化,但是CAS还是会成功。

Java中CAS机制使用版本号进行对比,避免ABA问题。

synchronized

适用场景:悲观认为并发很高,需要阻塞,需要上锁。

特点:语言层面的优化,锁粗化、偏向锁、轻量锁等等;可读性高。

ReentrantLock 和 Atomic类

以上两种并发工具都使用了CAS机制。 

在并发不高竞争不激烈时候,性能略低于synchronized;相反,并发高竞争激烈时候,性能高于synchronized。

ReentrantLock相对于synchronized:

ReentrantLock等待可中断,synchronized不可以。

ReentrantLock需要手动释放锁,synchronized不需要。

ReentrantLock可支持公平非公平锁,synchronized只支持非公平锁。

ReentrantLock没有语言层面的优化,底层实现机制AQS和CAS,synchronized有优化。

ReentrantLock可重入锁,synchronized不可重入,可能导致死锁。

ReentrantLock支持读写锁,可以提高高并发读操作。

synchronized由操作系统支持,涉及内核态和用户态的上下文切换,并发高时切换开销非常大。

ReentrantLock(AQS)依赖volatile int变量标示锁状态,结构为双向链表的等待队列,通过(cas+死循环)更改锁状态,一旦更新成功,标示竞争到锁。

AQS释放锁: 

通过cas改变状态

private void doReleaseShared() {

        /*

        * Ensure that a release propagates, even if there are other

        * in-progress acquires/releases.  This proceeds in the usual

        * way of trying to unparkSuccessor of head if it needs

        * signal. But if it does not, status is set to PROPAGATE to

        * ensure that upon release, propagation continues.

        * Additionally, we must loop in case a new node is added

        * while we are doing this. Also, unlike other uses of        * unparkSuccessor, we need to know if CAS to reset status

        * fails, if so rechecking.

        */

        for (;;) {

            Node h = head;

            if (h != null && h != tail) {

                int ws = h.waitStatus;

                if (ws == Node.SIGNAL) {

                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))

                        continue;            // loop to recheck cases

                    unparkSuccessor(h);

                }

                else if (ws == 0 &&

                        !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))

                    continue;                // loop on failed CAS

            }

            if (h == head)                  // loop if head changed

                break;

        }

    }

获取锁: 

如果获取到锁,设为头节点,否则一直自旋等待,在高并发时,可以避免大量锁竞争的上下文切换,降低线程切换开销。

private void doAcquireInterruptibly(int arg)

        throws InterruptedException {

        final Node node = addWaiter(Node.EXCLUSIVE);

        boolean failed = true;

        try {

            for (;;) {

                final Node p = node.predecessor();

                if (p == head && tryAcquire(arg)) {

                    setHead(node);

                    p.next = null; // help GC                    failed = false;

                    return;

                }

                if (shouldParkAfterFailedAcquire(p, node) &&

                    parkAndCheckInterrupt())

                    throw new InterruptedException();

            }

        } finally {

            if (failed)

                cancelAcquire(node);

        }

    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容