Java那点琐事

Java中的锁有很多种,经常会听到“锁”这个词。

犹如每天出门时,🔑就是一种“锁”,拿不到🔑,就进不去了。

锁的种类

1 悲观 Vs 乐观

林妹妹比较悲观,宝玉比较乐观
悲观如林妹妹,怕多行一步路,怕多说一句话,被人耻笑了去。担心外人所说,“金石良缘”,怕宝玉的心思会变。不敢多表露心思,总是猜疑,总想去证明。

而宝玉,天性乐观一些,总觉得这个妹妹是见过的,总觉得以后就是会和这个妹妹在一起的,不需要多证明。“你证我证,心证意证。是无有证,斯可云证。无可云证,是立足境”。

1.1 悲观锁

看名字便知,它是悲观的,总是想到最坏的情况。
锁也会悲观,它并不是难过,它只是很谨慎,怕做错。

每次要读data的时候,总是觉得有“坏人”会修改数据,所以先加个🔐,让“坏人”不能改数据,再慢慢读~
就像你每次出门用🔑锁门一样。

应用:
synchronized关键字和Lock的实现类都是悲观锁。

1.2 乐观锁

它很乐观,总是想着最好的情况。
它比较大条,不会太担心。如果要发生,总会发生,如果不会发生,那就不会。为什么要担心那么多?

每次读data时,总是乐观地想没有“坏人”会同时修改数据,不用加锁,放心地读data。
但在更新的时候会判断一下在此期间别人有没有去更新这个数据。

相信“天下无贼”。

事事无绝对,悲观也好乐观也好,没有绝对的悲观,也没有绝对的乐观。只是在这个当时,相信,还是不相信。

悲观锁 Vs 乐观锁

类型 实现 使用场景 缺点
悲观锁 synchronized关键字和Lock的实现类 适合写操作多的场景,可以保证写操作时数据正确 如果该事务执行时间很长,影响系统的吞吐量
乐观锁 无锁编程,CAS算法 适合读操作多的场景,能够大幅提升其读操作的性能 如果有外来事务插入,那么就可能发生错误

乐观锁之CAS(Compare and Swap 比较并交换)

是乐观锁的一种实现方式。

简单来说,有3个三个操作数:

  • 需要读写的内存值 V。
  • 进行比较的值 A。
  • 要写入的新值 B。

2 公平 Vs 非公平

没有绝对的公平,也没有绝对的不公平。

公平,就是按顺序排队嘛。
公平锁维护了一个队列。要获取锁的线程来了都排队。

waitQueue.png

非公平,上来就想抢到锁,好像一个不讲道理的,抢不到的话,只好再去乖乖排队了。
非公平锁没有维护队列的开销,没有上下文切换的开销,可能导致不公平,但是性能比fair的好很多。看这个性能是对谁有利了。

3 独享 Vs 共享

好比你自己的自行车,就是你独享的资源。
OFO、摩拜单车,就是共享的资源,但也是一次只能一个人用啦。更好的例子,比如说一条小溪,可以同时好几只小鹿在溪边喝水小溪就是共享的嘛~

4 可重入锁 Vs 非可重入锁

广义上的可重入锁,而不是单指JAVA下的ReentrantLock。

可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响。

这句话神马意思?

这种锁是可以反复进入的。

当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。

class MyClass {
    public synchronized void method1() {
        enterNextRoom();
    }

    public synchronized void method2() {
        // todo
    }
}

两个方法method1和method2都用synchronized修饰了,假如某一时刻,线程A执行到了method1,此时线程A获取了这个对象的锁,而由于method2也是synchronized方法,假如synchronized不具备可重入性,此时线程A需要重新申请锁。但是这就会造成一个问题,因为线程A已经持有了该对象的锁,而又在申请获取该对象的锁,这样就会线程A一直等待永远不会获取到的锁。

可重入锁最大的作用是避免死锁。

  • synchronized
  • ReentrantLock

构造函数提供了是否公平锁的初始化

/**
     * Creates an instance of {@code ReentrantLock}.
     * This is equivalent to using {@code ReentrantLock(false)}.
     */
    public ReentrantLock() {
        sync = new NonfairSync();
    }

    /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

使用ReentrantLock必须在finally控制块中进行解锁操作。

在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍,而ReentrantLock确还能维持常态。

高并发量情况下使用ReentrantLock。

优点:
可一定程度避免死锁。

  • Semaphore
  • AtomicInteger、AtomicLong等

参考:

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

推荐阅读更多精彩内容

  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,697评论 0 11
  • 在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制。Java提供了多种多线程锁机制的实现方...
    千淘萬漉阅读 6,896评论 1 33
  • 虽然我知道你也是一脸懵逼的进来,一脸懵逼的出去,但是等你深入了解后,你会收益匪浅的,小白可以先收藏起来 其实如果按...
    java后端学习阅读 3,968评论 0 16
  • 目录 常用锁 synchronized ReentrantLock ReadWriteLock Semaphore...
    齐晋阅读 9,969评论 4 29
  • 在花盆里扔进了四叶草的种子。 土没有翻过,里面还有上一株植物的残骸,浇的水不知道是什么时候装进瓶子又在阳台上搁置了...
    喵了个呜哇阅读 351评论 1 3