ReentrantLock 重入锁

SAP FICO会计凭证过账接口 -------------------------------------增加职能范围-ZHANGZG-2022.09.07 注释掉-2022.09.20。CONCATENATE '总账' ls_doc_item-hkont '要求输入成本对象值!*-------------------------------------增加职能范围-ZHANGZG-2022.09.07。*-------------------------------------增加职能范围-ZHANGZG-2022.09.07。 阅读详情

锁分类参考文章

基本使用

1.继承与实现

public class ReentrantLock implements Lock, java.io.Serializable 

Lock 接口

// 如果锁可用就获得锁,如果锁不可用就阻塞直到锁释放
void lock();
// 和lock()方法相似, 但阻塞的线程 可 中 断 , 抛 出java.lang.InterruptedException 异常
void lockInterruptibly() throws InterruptedException;
// 非阻塞获取锁;尝试获取锁,如果成功返回 true
boolean tryLock();
//带有超时时间的获取锁方法
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
// 释放锁
void unlock();
Condition newCondition();

2.ReentrantLock 重入锁

重入锁,表示支持重新进入的锁,也就是说,如果当前线程 t1 通过调用 lock 方法获取了锁之后,再次调用 lock,是不会再阻塞去获取锁的,直接增加重试次数就行了。synchronized 和 ReentrantLock 都是可重入锁。

  • 可中断
  • 可以设置超时时间
  • 可以设置为公平锁
  • 支持多个条件变量

基本语法

	//获取锁
	reetrantLock.lock();
	try{
	    //临界区
	}finally{
	    //释放锁
	    reentrantLock.unlock();
	}

可重入

可重入指一个线程如果首次获取这把锁,他就是这把锁的拥有者,有权再次获取这把锁。如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住。

可打断

如果用的lock.lockInterruptibly()这个方法上锁的话,别的线程是可以通过interrupt方法打断的。比如:我的a线程正在尝试获取锁,但这个lock已经被b线程拿了,b可以如果执行Interrupt就可以把a线程正在尝试的打断直接获取失败不等待。就是一种防止无限制等待的机制,避免死等,减少死锁的产生。

锁超时

有个lock.tryLock()方法,返回boolean,获取到就返回true,获取不到锁就返回false,这个方法的可以传入两个参数超时时间,第一个参数数字代表时间,第二个是单位。代表他去tryLock()尝试获取锁的时候最多等待的实践,如果是1和秒就是最多尝试等待一秒,还没拿到就返回false。也是一直超时机制,防止死锁。

公平锁

syn就是非公平的,重量级的monitor的堵塞队列就是非公平的。
ReentrantLock默认是不公平,但是我们可以通过构造方法改成公平的,传的是boolean值

条件变量

syn不满足条件的线程都在一个休息室
而ReentranLock支持多休息室,唤醒的时候也是按照休息室来唤醒
使用流程:

  • await进行等待(前需要获得锁)
  • await执行后,会释放锁,进入conditionObject等待
  • await的线程被唤醒(或打断或超时)去重新竞争lock锁
  • 竞争lock锁成功后,从await后继续执行

在new完ReentranLock之后可以用newCondition()方法创建休息室,然后就可以用new出来的condition调用await方法进入休息室等待,唤醒的话是signal()方法

3.可调用的方法

在这里插入图片描述

4.构造

	public ReentrantLock() {
        sync = new NonfairSync();
    }
    //fair true 创建公平锁
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

5.获取锁

	//获取锁,获取不到,会等待知道获取
	public void lock() {
        sync.lock();
    }
    //可被其它线程打断的锁
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }
    //直接获取锁,成功则返回true 失败返回fasle
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
    //指定时间范围获取锁,传入超时时间和单位
    public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }

6.释放锁

	public void unlock() {
        sync.release(1);
    }

7.查看锁的状态

	//查询此锁是否由任何线程持有。此方法设计用于监视系统状态,而不是用于同步控制。
	public boolean isLocked() {
        return sync.isLocked();
    }

8.是否是公平锁

	public final boolean isFair() {
        return sync instanceof FairSync;
    }

9.tostring

	//返回类型名@hashcode值,是否被锁,锁着的时候返回线程名
	//java.util.concurrent.locks.ReentrantLock@30ee82d7[Locked by thread Thread-0]
	public String toString() {
        Thread o = sync.getOwner();
        return super.toString() + ((o == null) ?
                                   "[Unlocked]" :
                                   "[Locked by thread " + o.getName() + "]");
    }

测试使用

public class Test5 {
	static ReentrantLock reentrantLock = new ReentrantLock();
	static Test5 test5;
	static Thread thread1;
	public static int a = 5;
	public void test() {
		System.err.println("hashCode"+reentrantLock.hashCode());
		boolean tryLock;
		try {
			tryLock = reentrantLock.tryLock(5, TimeUnit.SECONDS);
			System.err.println("getHoldCount:"+reentrantLock.hasQueuedThreads());
			
			/*Condition newCondition = reentrantLock.newCondition();
			newCondition.awaitUninterruptibly();*/
			System.out.println("线程"+Thread.currentThread().getName()+":开始调用Test5");
			System.out.println("线程"+Thread.currentThread().getName()+":拿到锁"+reentrantLock.isLocked());
			if(!tryLock)
				return;
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		try {
			try {
				for (int i = 0; i < 20; i++) {
					Thread.sleep(10);
					a++;
					System.out.println("线程"+Thread.currentThread().getName()+":"+ a);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} finally {
			System.out.println("线程"+Thread.currentThread().getName()+":释放锁");
			reentrantLock.unlock();
		}
	}
	public static void main(String[] args) {
		
		thread1 = new Thread() {
			public void run() {
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				test5 = new Test5();
				test5.test();
				
			};
		};
		thread1.start();
		
		new Thread() {
			public void run() {
				test5 = new Test5();
				test5.test();
			};
		}.start();
		
		new Thread() {
			public void run() {
				try {
					Thread.sleep(60);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.err.println("getHoldCount:"+reentrantLock.getHoldCount());
			};
		}.start();
	}
}

源码实现

1.Sync

abstract static class Sync extends AbstractQueuedSynchronizer 
		abstract void lock();
		final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }
        protected final boolean isHeldExclusively() {
            // While we must in general read state before owner,
            // we don't need to do so to check if current thread is owner
            return getExclusiveOwnerThread() == Thread.currentThread();
        }
        final ConditionObject newCondition() {
            return new ConditionObject();
        }
        // Methods relayed from outer class
        final Thread getOwner() {
            return getState() == 0 ? null : getExclusiveOwnerThread();
        }
        final int getHoldCount() {
            return isHeldExclusively() ? getState() : 0;
        }
        final boolean isLocked() {
            return getState() != 0;
        }
        /**
         * Reconstitutes the instance from a stream (that is, deserializes it).
         */
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();
            setState(0); // reset to unlocked state
        }

2.NonfairSync

	static final class NonfairSync extends Sync{
		private static final long serialVersionUID = 7316153563782823691L;
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);//AbstractQueuedSynchronizer 的方法
        }
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }}

3.FairSync

	static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;
        final void lock() {
            acquire(1);
        }
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

下篇文章继续学习

Altium Designer实战:手把手教你设计智能车竞赛疯狂电路组赛道(附封装库) 本文详细介绍了使用Altium Designer软件进行智能车竞赛“疯狂电路”组赛道设计的全流程实战指南。从理解比赛规则、搭建设计环境、创建专用元器件封装库,到电路布局、路径规划及设计输出验证,手把手教你高效完成符合计分标准的赛道图纸设计,并附上实用的封装库管理方法。 阅读详情

相关推荐

Hypermesh联合ABAQUS—Sets的建立和编辑

打开part copy对话框在对话框的最上面位置可以输入copy后的名称,然后将最下面的Separate disconnected regions into parts(将不连续的区域分割成parts)选项的前面方框勾选上。打开abaqus软件界面,File→import→model,将file filter选为inp格式,找到要导入的有限元文件,单击OK导入文件。HyperWorks新建Set时,会在Model Browser显示,打开Create Set对话框显示详细信息。快捷键,高亮set的内容。

动力资料屋的博客 1292

ReentranLock(可重入锁)

条件变量synchronized 中也有条件变量,就是我们讲原理时那个 waitSet 休息室,当条件不满足时进入 waitSet 等待ReentrantLock 的条件变量比 synchronized 强大之处在于,它是支持多个条件变量的,这就好比● synchronized 是那些不满足条件的线程都在一间休息室等消息● 而 ReentrantLock 支持多间休息室,有专门等烟的休息室、专门等早餐的休息室、唤醒时也是按休息室来唤醒使用要点:● await 前需要获得锁。

m0_56188609的博客 1262

Project 编制进度计划【项目管理】

Project 项目管理编制进度计划详解。

m0_52861684的博客 5088

重入锁ReentrantLock详解

ReentrantLock是Java并发包中提供的一种功能强大、使用灵活的可重入锁。它支持公平锁和非公平锁、显式锁控制、尝试非阻塞地获取锁、支持超时尝试获取锁、支持中断以及条件变量等特性。

qq_38875964的博客 1632

【导航】ESP32 教学篇目录 【快速跳转】

本文章 来自原创专栏《ESP32教学专栏 (基于ESP-IDF)》,讲解如何使用 ESP-IDF 构建 ESP32 的WIFI及连接的程序,发布文章并会持续为已发布文章添加新内容! 每篇文章都经过了精打细磨! ↓↓↓通过下方 按钮 进入专栏主页↓↓↓ 专栏主页:点击进入→ESP32 教学专栏 (基于ESP-IDF) WIFI二级专栏:点击进入→ESP32 上的 WiFi ............

Augtons 的博客 3万+

OpenHarmony自定义Launcher

OpenHarmony源码版本:4.0release开发板:DAYU / rk3568DevEco Studio版本:4.0.0.600切换分支为OpenHarmony-4.0-Release,并下载源码。

Abner_Crazy的博客 1630

ReentrantLock可重入锁⭐️通过具体案例分析其工作流程以及实现原理

前言小伙伴们大家好,上次分析volatile关键字,这次来分析下ReentrantLock,也就是可重入锁。

产品经理克星(狗头) 1769

ROS 2 Slam Toolbox实战:从零跑通2D激光建图

SLAM(同步定位与地图构建)是移动机器人实现自主导航的基础技术,其核心在于通过传感器数据实时估计位姿并构建环境栅格地图。slam_toolbox作为ROS 2 Humble及后续LTS版本官方主推的2D SLAM后端,采用图优化+闭环检测架构,兼顾实时性、鲁棒性与工程可维护性。相比cartographer和hector_slam,它原生支持ROS 2、参数精简、诊断友好,特别适合硬件资源有限、缺乏IMU或深度相机的差速机器人平台。本文聚焦真实部署场景,覆盖RPLIDAR等常见2D激光雷达与TurtleBo

weixin_30596165的博客 358

Java 并发编程(七): 重入锁 ReentrantLock

ReentrantLock 重入锁简介 重入锁 ReentrantLock,顾名思义,就是支持同一个线程对资源的重复加锁。另外,该锁还支持获取锁时的公平与非公平性的选择。 重入锁 ReentrantLock,只支持独占方式的获取操作,因此它只实现了 tryAcquire、tryRelease 和 isHeldExclusively 方法。 ReentrantLock 如何实现锁重入 ...

码客 249

写出GD32L233/235在读写flash的区别(用于OTA功能)

在单片机里面表示 大概是 address += sizeof(uint32_t) address += sizeof(uint64_t)1.说到OTA功能,实际上 往flash 指定区域写 数据, 拷贝数据,然后 跳转, 必要时 注意单片机的偏移量。在写本文时,L233支持单字写入,而L235只有双字写入. 一个写入地址+4 一个写入地址+8。这个是 自己写的擦除一页 数据,当然可以参考 提供的demo去实现,看自己需求。接下来是 读取 双字,也就是在L235上的读取。

teleger的博客 908

从开票数据到 ML81N 一键过账:用 ABAP BAPI 批量创建 Service Entry Sheet 的落地方案

摘要:SAP ESM场景中,服务履约确认通常通过ML81N事务码创建服务条目表(SES)完成。本文介绍如何基于开票数据(VBRK/VBRP)自动生成SES:首先通过BAPI_PO_GETDETAIL获取采购订单服务行结构,然后使用BAPI_ENTRYSHEET_CREATE创建SES并覆盖开票数量与金额,最后调用BAPI_ENTRYSHEET_RELEASE自动释放。解决方案包含ALV交互界面、批量处理逻辑和结果跳转功能,实现从人工录入到自动化处理的转变。(149字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 330

ReentrantLock — 可重入锁

J.U.C Java.util.concurrent(java并发应用包) 是在并发编程中比较常用的工具类,里面包含很多用来在并发场景中使用的组件。比如线程池、阻塞队列、计时器、同步器、并发集合等等。并发包的作者是大名鼎鼎的 Doug Lea。 ReentrantLock Lock在J.U.C中是最核心的组件,J.U.C 包中的所有组件绝大部分的组件都有用到了 Lock。在 Lock 接口出现之前,Java中的应用程序对于多线程的并发安全处理只能基于synchronized关键字来解决。Reentra

leimeng123的博客 1813

AUTOSAR内存篇 -内存驱动(Mem)

Mem驱动程序的task是基于底层内存设备技术的物理分段的低级内存访问。Mem驱动程序的API与内存设备技术无关,因此向存储器访问模块上层提供了与存储器设备无关的接口。所有高级功能(如跨段操作)都由内存访问模块处理,以尽可能降低Mem驱动器的复杂性和占用空间。Mem驱动API命名、类型定义和文件命名规则都遵循标准的AUTUSAR BSW模块实现。服务Mem_Init初始化Mem驱动的内部状态,并设置Mem驱动Job处理状态到MEM_JOB_OK。

IOT2017的博客 714

ReentrantLock重入锁

重入锁,顾名思义,就是支持重新进入的锁,表示这个锁能够支持一个线程对资源重复加锁。如果一个线程已经拿到了锁,那么他需要再次获取锁的时候不会被该锁阻塞。举个例子,test和test2都是同步方法,在执行之前都需要上锁,执行test获取到了锁,test里面调用test2,如果是重入锁,锁识别到获取锁的线程就是当前线程,那么直接进入。如果锁不支持重入,那么显然执行会阻塞在test2()这个位置。当然,synchronized和ReentrantLock都是重入锁,均支持重新进入。

m0_59925573的博客 371

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

重入锁ReentrantLock

一、什么是重入锁   锁,是多线程控制临界区资源访问的有效方法。重入锁,顾名思义就是可以对同一个线程进行多次加锁的一个锁类型。对于每一次的加锁都得有对应的解锁。 1.1 重入锁的简单使用 package com.zhaotq.lab.thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockDemo imp

hanxirensheng的专栏 185

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

详述重入锁-ReentrantLock

什么是重入锁? 锁主要用来控制多线程访问的行为,对于同一个线程,如果连续两次对同一把锁进行lock,那么这个线程会被卡死在那里,这样的特性很不好,在实际的开发中,方法之间的调用方式错综复杂,如果不小心可能在多个不同的方法中,反复调用 lock(),这样就会把自己卡死。 所以,重入锁就是用来解决这个问题的,重入锁使同一个线程可以对同一把锁在不释放的前提下,反复的加锁不会导致线程的卡死,唯一的一点就是需要保证 unlock() 的次数和 lock()一样的多。 重入锁的实现 Java中的锁都来自与 Lock

养歌的博客 4247

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

重入锁 ReentrantLock

1.synchronized的功能扩展:重入锁     重入锁可以完全替代synchronized关键字。在JDK5.0的早期版本中,重入锁的性能远远的好于synchronized,但是从JDL6.0开始,JDK在synchronized上做了大量的优化,使两者的性能差距并不大。     重入锁使用java.util.concurrent.locks.ReentrantLock类来实现,我们先...

王金铎的博客 309

Java并发重入锁ReentrantLock

ReentrantLock 重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源重复加锁,即当前线程获取该锁后再次获取不会被阻塞。

wswpomos的博客 4399

ReentrantLock如何实现重入锁?

  问题    (1)重入锁是什么?    (2)ReentrantLock如何实现重入锁?    (3)ReentrantLock为什么默认是非公平模式?    (4)ReentrantLock除了可重入还有哪些特性?    简介    Reentrant = Re + entrant,Re是重复、又、再的意思,entrant是enter的名词或者形容词形式,翻译为进入者或者可进入的,...

weixin_30882895的博客 436

多线程之重入锁ReentrantLock及原理

重入锁是sunchronized、Object.wait()和Object.notify()方法的替代品(或者说是增强版),在JDK5.0的早期版本,重入锁的性能远远好于synchronized,但从JDK6.0开始,JDK在synchronized上做了大量的优化,使得两者的性能差距并不大。但ReentrantLock也有一些synchronized没法实现的特性。 重入锁,为啥要叫重入锁呢,

qq_31957747的博客 1249

【Java并发】- ReentrantLock,重入锁

ReentrantLock概述ReentrantLock(重入锁),顾名思义是可以重新进入的锁,也就是说当一个线程获取了这个锁之后还能在释放锁之前再次获取这个锁,同时还支持公平所和非公平锁的选择。ReentrantLock的重入重入例子synchronized就很好的支持了重入: 例: public class ReentrantLockDemo { public static void m

LightOfMiracle的博客 645

ReenTrantLock重入锁

ReenTrantLock(重入锁) 非公平性锁(默认):不是按照先后顺序,而是按照抢占式来获得锁, 公平性锁(false):按照线程请求锁的顺序来获取锁 具体的剖析: ReenTrantLock实现Lock和序列化接口 三个内部类:ync、NonfairSync、FairSync 抽象类Sync继承了 AbstractQueuedSynchronizer(AQS)类 构造函数: Reent...

weixin_43356265的博客 311
上一篇: java 集合 学习记录
下一篇: java ReentrantLock NonfairSync和FairSync源码实现
bml_bml
博客等级 码龄9年 71粉丝 17原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值