Java锁系列教程之独占式锁

在Java并发编程中,锁是一个很重要的对象。Java中锁有两种:隐式锁和显式锁。使用synchronized关键字的锁是隐式锁。因为锁的申请和释放都是由JVM来维护的,不用我们来手动处理。使用Java并发包locks包下的锁,需要使用者手动申请和手动关闭。这种形式是显式锁。如果按照多个线程能不能共享同一个锁(资源)来分的话,可以分为独占式(排他)锁和共享锁。其中synchronized关键字的锁和ReentrantLock锁的锁都是独占式锁。

通过前面三篇文章的学习,我们知道了同步组件基础框架-AbstractQueuedSynchronizer(AQS) 同步器。在同步器的方法中有两种方式获取锁:独占式和共享式锁。我们先来学习独占式锁-ReentrantLock。

本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《Lock系列》教程的第四篇:《Java并发包下锁学习第四篇:ReentrantLock》。

编辑

ReentrantLock使用语法

我们知道并发包下的lock是显式锁,需要手动获取锁和手动释放锁。所以语法如下:

ReentrantLock lock = new ReentrantLock();

try {

lock.lock();

//TODO

}finally {

lock.unlock();

}

获取锁:lock.lock();

释放锁:lock.unlock();

在try中获取到锁;在finally中释放锁。

因为必须释放锁。所以,必须在finally中进行释放锁操作。而且释放锁操作必须放在finally的第一行。

独占式锁理解:

生活中的例子:

在自动ATM机上取钱的时候,我们需要排队,当一个人在操作ATM机取钱的时候,下一个人就需要在ATM机黄线外面等待(排除和取钱人一起去的人)。假设路人甲在操作ATM机的时候,我们其他后面排队的人是不是需要等待着,路人甲从ATM机区域出来后才可以进行操作ATM机。这个操作过程如果放在我们多线程并发角度来思考的话:共享数据是ATM机,多个线程是多个存取钱的人。当路人甲在操作ATM机的时候路人甲获取到ATM机操作权限可以理解为lock.lock()操作。这个时候,共享数据ATM机就会被路人甲独自一个人占用了(独占式获取到了共享数据(或者是锁))。当路人甲操作完离开ATM机这个操作可以理解为lock.unlock()操作。

从上了生活例子中我们可以这么理解独占式锁,所谓的独占式锁就是同一时刻只能有且只有一个线程获取到锁且操作成功,其他线程只能等待释放锁后,在进行操作。

需要说明的是,在Java中隐式锁(synchronized关键字修饰的)也是独占式锁的一种体现。

使用方法一:独占非公平演示

需求:使用三个线程,调用一个方法,在方法内睡眠2s.代码下图:

查看运行结果:

线程2开始获取锁。

线程3开始获取锁。

线程1开始获取锁。

线程2获取到了锁。开始做其他的操作了====do..........

======关闭锁=======

线程3获取到了锁。开始做其他的操作了====do..........

======关闭锁=======

线程1获取到了锁。开始做其他的操作了====do..........

======关闭锁=======

从上图运行结果,我们可以分析出:

1:线程的顺序和我们线程运行的顺序不一致

2:每次只能有一个线程执行完关闭锁之后,其他线程才可以接着使用。

从示例代码,我们可以得到如下总结:

1:reentrantLock是独占式锁;

2:默认情况下不能保证获取锁的顺序和线程执行顺序的一致性。

如果想要保证线程执行顺序和获取锁的顺序一致性,也是可以操作的。在下一篇文章中,凯哥将讲解怎么操作。

​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​欢迎来聊

Java并非锁之独占非公平锁理解的更多相关文章

  1. Java多线程系列--“JUC锁”05之 非公平锁

    概要 前面两章分析了"公平锁的获取和释放机制",这一章开始对“非公平锁”的获取锁/释放锁的过程进行分析.内容包括:参考代码获取非公平锁(基于JDK1.7.0_40)释放非公平锁(基 ...

  2. Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...

  3. Java中的公平锁和非公平锁实现详解

    前言 Java语言中有许多原生线程安全的数据结构,比如ArrayBlockingQueue.CopyOnWriteArrayList.LinkedBlockingQueue,它们线程安全的实现方式并非 ...

  4. Java 公平锁与非公平锁学习研究

    最近学习研究了一下Java中关于公平锁与非公平锁的底层实现原理,总结了一下. 首先呢,通过其字面意思,公平与非公平的评判标准就是付出与收获成正比(和社会中的含义差不多一个意思).放到程序中,尤其是 在 ...

  5. 死磕 java同步系列之ReentrantLock源码解析(一)——公平锁、非公平锁

    问题 (1)重入锁是什么? (2)ReentrantLock如何实现重入锁? (3)ReentrantLock为什么默认是非公平模式? (4)ReentrantLock除了可重入还有哪些特性? 简介 ...

  6. Java锁--非公平锁

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3496651.html 参考代码 下面给出Java1.7.0_40版本中,ReentrantLock和AQ ...

  7. 浅谈Java中的公平锁和非公平锁,可重入锁,自旋锁

    公平锁和非公平锁 这里主要体现在ReentrantLock这个类里面了 公平锁.非公平锁的创建方式: //创建一个非公平锁,默认是非公平锁 Lock lock = new ReentrantLock( ...

  8. 第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()

    最常用的方式: int a = 12; //注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁与copyOnWriteArrayList中的全局锁 final Reentrant ...

  9. 多线程编程-- part5.1 互斥锁之非公平锁-获取与释放

    非公平锁之获取锁 非公平锁和公平锁在获取锁的方法上,流程是一样的:它们的区别主要表现在“尝试获取锁的机制不同”.简单点说,“公平锁”在每次尝试获取锁时,都是采用公平策略(根据等待队列依次排序等待):而 ...

  10. 理解ReentrantLock的公平锁和非公平锁

    学习AQS的时候,了解到AQS依赖于内部的FIFO同步队列来完成同步状态的管理,当前线程获取同步状态失败时,同步器会将当前线程以及等待状态等信息构造成一个Node对象并将其加入到同步队列,同时会阻塞当 ...

随机推荐

  1. MySQL - CASE WHEN的高级用法

    Case语法 CASE WHEN condition1 THEN result1 WHEN condition2 THEN result2 WHEN conditionN THEN resultN E ...

  2. 算法金 | 致敬深度学习三巨头:不愧是腾讯,LeNet问的巨细。。。

    ​ 大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 抱个拳,送个礼 读者参加面试,竟然在 LeNet 这个基础算法上被吊打~ LeNe ...

  3. 重复消费Java Stream的三种方法。你选择哪种?

    Java中的Stream一旦被消费就会关闭,不能再次使用了.如果的确有需要该怎么办呢? 这里介绍三种重复消费Stream的方法. 1. 从集合再次创建 这里你都不用往下继续看就知道该怎么办,不过我还是 ...

  4. 外部网关协议BGP

    不能全部使用RIP与OSPF的原因有二:互联网规模太大,自治系统间路由选择困难:自治系统间路由选择必须考虑有关策略. 在每一个自治系统中有两种不同功能的路由器,边界路由器和内部路由器. BGP四种报文 ...

  5. 探索Nuxt.js的useFetch:高效数据获取与处理指南

    title: 探索Nuxt.js的useFetch:高效数据获取与处理指南 date: 2024/7/15 updated: 2024/7/15 author: cmdragon excerpt: 摘 ...

  6. MySQL索引是怎么支撑千万级表的快速查找?

    前言 在 MySQL 官方提到,改善操作性能的最佳方法 SELECT 在查询中测试的一个或多个列上创建索引.索引条目的作用类似于指向表行的指针,从而使查询可以快速确定哪些行与WHERE子句中的条件匹配 ...

  7. mysql:Windows修改MySQL数据库密码(修改或忘记密码)

    今天练习远程访问数据库时,为了方便访问,就想着把数据库密码改为统一的,以后我们也会经常遇到MySQL需要修改密码的情况,比如密码太简单.忘记密码等等.在这里我就借鉴其他人的方法总结几种修改MySQL密 ...

  8. stream流的概述以及idea与stream

    前面自己学过一些流的概念,比如IO流,用于读写本地的数据. stream流主要是用于对集合/数组进行操作 idea现在已经很好的支持Stream流操作,在debug的时候可以很好的看到详细内容 下面以 ...

  9. C语言中的断言函数assert

    简介 assert 是 C 语言中的一个宏,用于在程序运行时进行条件检查,主要用于调试目的.它在 <assert.h> 头文件中定义,用于验证程序中的假设条件是否成立,如果不成立,程序将打 ...

  10. 【MySQL】DB-Link 跨库访问

    相关说明: https://blog.csdn.net/qq_48721706/article/details/124088963 DB-LINK以一个远程访问方式访问其他MYSQL实例 连接实例和被 ...