ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java锁机制

2020-10-09 23:01:14  阅读:206  来源: 互联网

标签:Java lock ReentrantLock 线程 公平 new 机制 public


上一篇简略说了一下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(读锁),其中写锁是独占锁,读锁是共享锁,保证高并发。读写,写读,写写的过程是互斥的。其这些特性可用于缓存机制。

=======================================================

我是Liusy,一个喜欢健身的程序员。

提前祝大家伙中秋国庆快乐!!!

欢迎关注微信公众号【Liusy01】,一起交流Java技术及健身,获取更多干货。

标签:Java,lock,ReentrantLock,线程,公平,new,机制,public
来源: https://www.cnblogs.com/liusy01/p/13789421.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有