专栏首页Liusy01Java锁机制

Java锁机制

上一篇简略说了一下Synchronized和Lock,今天就来说一下Java的锁机制。

Java的锁机制主要分为四种,分别是

(1)公平锁、非公平锁

(2)可重入锁

(3)自旋锁 (4)共享锁、独占锁

接下来一一说一下这四种锁

一、公平锁、非公平锁

(1)公平锁:指多个线程按照申请锁的顺序来获取锁,类似于日常的排队

(2)非公平锁:多个线程获取锁的顺序并不是按照申请锁的顺序来,通俗来说就是插队

(3)ReentrantLock默认是非公平的

public ReentrantLock() {
    sync = new NonfairSync();
}

也可以是公平的

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

另外,synchronized也是非公平的,非公平的吞吐量比较大

(4)区别:公平锁会维护一个先进先出的线程等待队列,非公平锁是直接获取锁,上去就干,干不过人家再采取公平锁的方式。

公平锁:

非公平锁:

二、可重入锁(又叫递归锁)

(1)是指同一线程外层函数获取锁之后,内层递归函数仍然能持有锁继续运行。

ReentrantLock和synchronized都是可重入锁,比如下面这个demo

 static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
    for (int i = 0; i < 5; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                first();
            }
        }).start();
    }
}
public static void first() {
    lock.lock();
    try{
        System.out.println(Thread.currentThread().getName()+":11111111111");
        Thread.sleep(1000);
        second();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}
public static void second() {
    lock.lock();
    try{
        System.out.println(Thread.currentThread().getName()+":22222222222");
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

运行结果如下:

(2)可重入锁最大的作用就是避免死锁

(3)上一篇也说到了,ReentrantLock可以锁多次,但同样也要释放锁多次。因为锁是有一个状态字段state标明锁状态的,每锁一次就+1,解锁一个就-1,只有状态为0,才是完全解锁。

public static void first() {
  lock.lock();
  lock.lock();
  try{
      System.out.println(Thread.currentThread().getName()+":11111111111");
  } catch (Exception e) {
      e.printStackTrace();
  } finally {
      lock.unlock();
      lock.unlock();
  }
}

三、自旋锁

自旋锁在之前解析原子性时就说过了,主要是通过Unsafe+cas实现。

指尝试获取锁的线程不会阻塞,而是采用死循环的方式去尝试获取锁,会消耗大量的cpu

例如:

AtomicReference<Integer> atomicReference = new AtomicReference<>(0);
public void zxLock(){
    while (!atomicReference.compareAndSet(0,1)) {
    }
}

四、独占锁(写锁)、共享锁

(1)独占锁:指锁在某一时刻只能由一个线程持有,比如ReentrantLock和synchronized。

(2)共享锁:指锁可以同时被多个线程持有。

对于ReentrantReadWriteLock来说,其由ReadLock(写锁)和WriteLock(读锁),其中写锁是独占锁,读锁是共享锁,保证高并发。读写,写读,写写的过程是互斥的。其这些特性可用于缓存机制。

本文分享自微信公众号 - Liusy01(Liusy_01),作者:Liusy01

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Netty之MessagePack编解码框架

    一个高效的二进制序列化格式。它让你像JSON一样可以在各种语言之间交换数据。但是它比JSON更快、更小的整数会被编码成一个字节,短的字符串仅仅只需要比它的长度多...

    Liusy
  • ZK实现分布式锁

    上一篇说了ZK是什么以及能干什么,今儿这篇就来用ZK实现分布式锁,分别用java原生的zookeeper客户端、ZKClient实现。

    Liusy
  • 【设计模式-状态模式】

    【导读】人在不同的状态下会做出不同的行为,比如愤怒的时候会做一些出格的事,高兴的时候会分享快乐,这种就是状态模式。

    Liusy
  • Android 拦截WebView加载URL,控制其加载CSS、JS资源

    版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/49...

    Hankkin
  • Spring Cloud Stream 重点与总结

    原本想开个Spring Cloud Stream系列文章连载,写Spring Cloud Stream算是个人夙愿了——首先这是个人非常喜欢的组件,它屏蔽了各种...

    乱敲代码
  • Spring Cloud Stream 重点与总结

    原本想开个Spring Cloud Stream系列文章连载,写Spring Cloud Stream算是个人夙愿了——首先这是个人非常喜欢的组件,它屏蔽了各种...

    用户1516716
  • vue-cli引入vue-router

    同时在导航栏上方会有几个按钮,可以添加新的插件,如果我们之前没有安装过router插件,则会显示该按钮,点击安装即可。

    宣言言言
  • 【DB笔试面试405】​在一个关系R中,若每个数据项都是不可再分割的,那么R一定属于()

    ● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/

    小麦苗DBA宝典
  • 首次证明:牵手就能同步脑电波,还能缓解疼痛

    但实验数据可不会说谎,研究团队的西蒙妮(Simone Shamay-Tsoory)教授表示:

    量子位
  • 结合AI实现智能美颜相册

    “拍照技术不够,美颜滤镜来凑!”,美颜滤镜已经成了越来越多用户拍照的必备工具。那么如此常见的美颜技术要怎样才能应用在小程序中呢?如何用小程序·云开发结合AI技术...

    云加直播

扫码关注云+社区

领取腾讯云代金券