5. java 锁

重量级锁的原理与实战 重量级锁 阅读详情

锁分类

在这里插入图片描述

1. AQS(抽象队列同步器)

在这里插入图片描述
同步队列(即阻塞队列,线程处于blocked状态,头结点是获取了锁的节点)和等待队列(线程处于waiting状态),等待队列的节点/线程被执行signal()加入同步队列

公平锁只有同步队列的第一个节点能获取锁,非公平锁只有第一个或尚未加入的能获取锁;公平锁和非公平锁区别在于判断当前节点是否有前置节点
锁实际上是通过内部类Sync(即同步器;子类FairSync和NonfairSync)实现,而Sync继承自AbstractQueuedSynchronizer(AQS),AQS通过内部类Node(同步队列和等待队列的节点)和ConditionObject(条件获取锁)来实现锁的功能
在这里插入图片描述

在这里插入图片描述

应用

reentrantlock,CountDownLatch,CyclicBarrier,Semaphore中使用

加锁解锁流程

获取锁:

(ReentrantLock.lock()调用sync.acquire(1);acquire先tryAcquire,检查有无前置节点(公平锁),cas修改state状态;若成功则获取锁成功并返回;若失败则调用addWaiter加入同步队列,然后acquireQueued会判断addWaiter添加的节点如果是前驱节点是头节点,并且能够获得同步状态的话,当前线程能够获得锁该方法执行结束退出;否则先将节点状态设置成SIGNAL,然后调用LookSupport.park方法使得当前线程阻塞。)
(获取失败加入同步队列)

释放锁:

释放指定量的资源,如果彻底释放了(即state=0),它会唤醒同步队列里的其他线程来获取资源。(ReentrantLock.unlock()调用sync.release(1);release()先更新state,若更新后为0,则获取head节点,调用unparkSuccessor(h);unparkSuccessor调用LockSupport.unpark(head的next节点.thread)唤醒同步队列的下一节点,使其尝试获取锁)
(唤醒同步队列下一节点,从同步队列取出)

Node节点状态(waitStatus):

  1. CANCELLED:值为1,在同步队列中等待的线程等待超时或被中断,需要从同步队列中取消该Node的结点,其结点的waitStatus为CANCELLED,即结束状态,进入该状态后的结点将不会再变化。
  2. SIGNAL(同步队列中):值为-1,被标识为该等待唤醒状态的后继结点,当其前继结点的线程释放了同步锁或被取消,将会通知该后继结点的线程执行。说白了,就是处于唤醒状态,只要前继结点释放锁,就会通知标识为SIGNAL状态的后继结点的线程执行。
  3. CONDITION(等待队列中):值为-2,与Condition相关,该标识的结点处于等待队列中,结点的线程等待在Condition上,当其他线程调用了Condition的signal()方法后,CONDITION状态的结点将从等待队列转移到同步队列中, 等待获取同步锁。
  4. PROPAGATE:值为-3,与共享模式相关,在共享模式中,该状态标识结点的线程处于可运行状态。

加入等待队列/条件队列

condition是要和lock配合使用的也就是condition和Lock是绑定在一起的
使用场景
阻塞队列BlockingDeque

加入等待队列/条件队列
condition.await()方法后会使得当前获取lock的线程进入到等待队列,直至被signal/signalAll后会使得当前线程从等待队列中移至到同步队列中去,直到获得了lock后才会从await方法返回,或者在等待时被中断会做中断处理。

从等待队列中取出
调用condition的signal或者signalAll方法可以将等待队列中等待时间最长的节点移动到同步队列中,使得该节点能够有机会获得lock。

同步队列为什么是双向链表,而等待队列是单链表?

在队列同步器中,头节点是成功获取到同步状态的节点,而头节点的线程释放了同步状态后,将会唤醒其他后续节点,后继节点的线程被唤醒后需要检查自己的前驱节点是否是头节点,如果是则尝试获取同步状态。

final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
            	//线程被唤醒后继续执行循环体的操作
            	//获取前置节点并判断是否为head
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                //将节点状态设置为SIGNAL(同步队列)
                if (shouldParkAfterFailedAcquire(p, node) &&
                //阻塞当前线程
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

公平锁效率低

原因:

​ 公平锁要维护一个队列,后来的线程要加锁,即使锁空闲,也要先检查有没有其他线程在 wait,如果有自己要挂起,加到队列后面,然后唤醒队列最前面线程。这种情况下相比较非公平锁多了一次挂起和唤醒。

​ 线程切换的开销,其实就是非公平锁效率高于公平锁的原因,因为非公平锁减少了线程挂起的几率,后来的线程有一定几率逃离被挂起的开销。

2. 偏向锁

对象头

对象的内存布局(对象头,实例数据,填充数据)
对象头包括两部分信息,

  1. 用于存储对象自身的运行时数据(Mark word),如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,拥有锁的thread Id
  2. 类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
    对象的访问定位(句柄和直接引用(快))
    在这里插入图片描述
    在这里插入图片描述

锁的状态

  1. 无锁
  2. 偏向锁
  3. 轻量级锁
  4. 重量级所

对象头的mark word 记录拥有锁的thread Id,
线程的栈帧中存储对象头的mark word
在这里插入图片描述

(1)偏向锁

为什么要引入偏向锁?

因为经过HotSpot的作者大量的研究发现,大多数时候是不存在锁竞争的,常常是一个线程多次获得同一个锁,因此如果每次都要竞争锁会增大很多没有必要付出的代价,为了降低获取锁的代价,才引入的偏向锁。
适用场景
始终只有一个线程在执行同步块,在它没有执行完释放锁之前,没有其它线程去执行同步块

偏向锁的升级

当线程1访问代码块并获取锁对象时,会在java对象头和栈帧中记录偏向的锁的threadID,因为偏向锁不会主动释放锁,因此以后线程1再次获取锁的时候,需要比较当前线程的threadID和Java对象头中的threadID是否一致,如果一致(还是线程1获取锁对象),则无需使用CAS来加锁、解锁;如果不一致(其他线程,如线程2要竞争锁对象,而偏向锁不会主动释放因此还是存储的线程1的threadID),那么需要查看Java对象头中记录的线程1是否存活,如果没有存活,那么锁对象被重置为无锁状态,其它线程(线程2)可以竞争将其设置为偏向锁;如果存活,那么立刻查找该线程(线程1)的栈帧信息,如果还是需要继续持有这个锁对象,那么暂停当前线程1,撤销偏向锁,升级为轻量级锁,如果线程1 不再使用该锁对象,那么将锁对象状态设为无锁状态,重新偏向新的线程。

(2)轻量级锁

为什么要引入轻量级锁?

轻量级锁考虑的是竞争锁对象的线程不多,而且线程持有锁的时间也不长的情景。因为阻塞线程需要CPU从用户态转到内核态,代价较大,如果刚刚阻塞不久这个锁就被释放了,那这个代价就有点得不偿失了,因此这个时候就干脆不阻塞这个线程,让它自旋这等待锁释放。

轻量级锁什么时候升级为重量级锁?

线程1获取轻量级锁时会先把锁对象的对象头MarkWord复制一份到线程1的栈帧中创建的用于存储锁记录的空间(称为DisplacedMarkWord),然后使用CAS把对象头中的内容替换为线程1存储的锁记录(DisplacedMarkWord)的地址;
如果在线程1复制对象头的同时(在线程1CAS之前),线程2也准备获取锁,复制了对象头到线程2的锁记录空间中,但是在线程2CAS的时候,发现线程1已经把对象头换了,线程2的CAS失败,那么线程2就尝试使用自旋锁来等待线程1释放锁。
但是如果自旋的时间太长也不行,因为自旋是要消耗CPU的,因此自旋的次数是有限制的,比如10次或者100次,如果自旋次数到了线程1还没有释放锁,或者线程1还在执行,线程2还在自旋等待,这时又有一个线程3过来竞争这个锁对象,那么这个时候轻量级锁就会膨胀为重量级锁。重量级锁把除了拥有锁的线程都阻塞,防止CPU空转。

升降级关系

为了避免无用的自旋,轻量级锁一旦膨胀为重量级锁就不会再降级为轻量级锁了;偏向锁升级为轻量级锁也不能再降级为偏向锁。一句话就是锁可以升级不可以降级,但是偏向锁状态可以被重置为无锁状态。
在这里插入图片描述
在这里插入图片描述

(3)这几种锁的优缺点(偏向锁、轻量级锁、重量级锁)

在这里插入图片描述

自旋锁

Java原子类中的递增操作就通过CAS+自旋锁实现的

自旋锁原理非常简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗

3. Synchronized

原理简述:对象头的mark word指向monitor对象,monitor对象存有等待锁和持有锁的线程信息
详细说明
对象头是我们需要关注的重点,它是synchronized实现锁的基础,因为synchronized申请锁、上锁、释放锁都与对象头有关。对象头主要结构是由Mark Word 组成,其中Mark Word存储对象的hashCode、锁信息或分代年龄或GC标志等信息。

同步代码块是利用 monitorenter 和 monitorexit 指令实现的,而同步方法则是利用 flags 实现的。

在这里插入图片描述
重量级锁的指向互斥量的指针指向的是monitor对象(也称为管程或监视器锁)的起始地址。每个对象都存在着一个 monitor 与之关联,对象与其 monitor 之间的关系有存在多种实现方式,如monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成,但当一个 monitor 被某个线程持有后,它便处于锁定状态;monitor是由ObjectMonitor实现的;ObjectMonitor中有两个队列,_WaitSet 和 _EntryList,用来保存ObjectWaiter对象列表( 每个等待锁的线程都会被封装成ObjectWaiter对象),_owner指向持有ObjectMonitor对象的线程,当多个线程同时访问一段同步代码时,首先会进入 _EntryList 集合,当线程获取到对象的monitor 后进入 _Owner 区域并把monitor中的owner变量设置为当前线程同时monitor中的计数器count加1,若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入 WaitSe t集合中等待被唤醒。若当前线程执行完毕也将释放monitor(锁)并复位变量的值,以便其他线程进入获取monitor(锁)。如下图所示
在这里插入图片描述
在这里插入图片描述


 public synchronized static void aa(){ //类锁,方法
         }
        public synchronized  void aa(){ //对象锁,方法
         }

   synchronized (this){            //对象锁,代码块
            for(int i = 0;i < 100000;i++){
                sum++;
            }
        }

  synchronized (AA.class) {  //类锁,代码块
            System.out.println();
        }

4. ReenTrantLock

底层实现:

​ ReenTrantLock的实现是一种自旋锁,通过循环调用CAS操作来实现加锁。它的性能比较好也是因为避免了使线程进入内核态的阻塞状态。想尽办法避免线程进入内核的阻塞状态是我们去分析和理解锁设计的关键钥匙。

和synchronized区别

总结:jvm层面,不用手动释放,会阻塞,高级功能:可以非公平,可以中断,条件等待(Condition)

​ 1、底层实现:synchronized 是JVM层面的锁,是Java关键字,通过monitor对象来完成(monitorenter与monitorexit),ReentrantLock 是从jdk1.5以来(java.util.concurrent.locks.Lock)提供的API层面的锁。

​ 2、实现原理****:synchronized 的实现涉及到锁的升级,具体为无锁、偏向锁、自旋锁、向OS申请重量级锁;ReentrantLock实现则是通过利用CAS(CompareAndSwap)自旋机制**保证线程操作的原子性和volatile保证数据可见性以实现锁的功能。

​ 3、是否可手动释放:synchronized 不需要用户去手动释放锁,synchronized 代码执行完后系统会自动让线程释放对锁的占用; ReentrantLock则需要用户去手动释放锁,如果没有手动释放锁,就可能导致死锁现象。

​ 4、是否可中断synchronized是不可中断类型的锁,除非加锁的代码中出现异常或正常执行完成; ReentrantLock则可以中断,可通过trylock(long timeout,TimeUnit unit)设置超时方法或者将lockInterruptibly()放到代码块中,调用interrupt方法进行中断。

​ 5、是否公平锁synchronized为非公平锁 ReentrantLock则即可以选公平锁也可以选非公平锁,通过构造方法new ReentrantLock时传入boolean值进行选择,为空默认false非公平锁,true为公平锁,公平锁性能非常低。

5. cas(适用并发低,否则浪费cpu)

aba问题

6. 锁优化

编码层:减少锁时间和粒度,循环中的加锁放到循环外,适用cas,读写锁,并发包的锁等
系统层:自适应自旋锁,锁消除,锁升级

​ 自旋锁可以避免等待竞争锁进入阻塞挂起状态被唤醒造成的内核态和用户态之间的切换的损耗,它们只需要等一等(自旋),但是如果锁被其他线程长时间占用,一直不释放CPU,死等会带来更多的性能开销;自旋次数默认值是10

​ 对上面自旋锁优化方式的进一步优化,它的自旋的次数不再固定,其自旋的次数由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定,这就解决了自旋锁带来的缺点

鱼眼相机去畸变(图像拉直/展开/矫正)算法及实战总结 1、算法说明经纬度矫正法, 可以把鱼眼图想象成半个地球, 然后将地球展开成地图,经纬度矫正法主要是利用几何原理, 对图像进行展开矫正。经过P点的入射光线没有透镜的话,本应交于相机成像平面的e点。然而,经过鱼眼相机的折射,光线会交于相机成像平面的d点,就产生了畸变,因此畸变图像整体上呈现出像素朝图像中心点聚集的态势。而去畸变,就是将折射到d点的点,重新映射回到e点,因此去畸变之后的图像与原始的鱼眼图像相比,仿佛是把向心聚集的像素又重新向四周铺展开来。AVM环视系统——鱼眼相机去畸变算法 - 知乎。 阅读详情

相关推荐

lego-loam featureAssociation 源码注释(五)

上一次我们已经看完了特征提取,这次我们进入特征匹配的内容!!!systemInitedLM的初始值为false。

Joeybee的博客 886

【JAVA核心知识】20:synchronized实现原理与锁膨胀:无锁or偏向锁-轻量级锁-重量级锁,看完就懂

synchronized前言JDK对Synchronize的优化-锁膨胀偏向锁轻量级锁重量级锁重量级锁模式下的SynchronizeSynchronize 的核心组件Synchronized 的流程Synchronized 的实现Synchronized 的作用范围synchronized的简单使用 前言 Synchronized是通过对象内部的monitor(监视器锁)来实现的。monitor本质上又是依赖于底层操作系统的Mutex Lock来实现的,操作系统实现线程之间的切换 依赖于操作系统 Mutex

积 1806

通过HTTP的方式克隆GitHub上的项目

通过HTTP的方式克隆GitHub上的项目 打开想要下载的项目的网页链接,点击Clone or download绿色的按钮,进行如下步骤实现通过HTP的方式下载项目。 点击红色框圈出的位置: 打开想要存放项目的文件夹,在空白处点击鼠标右键,选择Git Bash Here,打开命令行。 输入git clone 复制的下载地址,回车进行下载。 4.正在下载的界面 5.下载完成。 技多不压身 哦耶✌✌✌ ...

weixin_37826412的博客 3201

细说 AQS(自旋、CLH)

阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费CPU时间。如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长。

肢解生活,直达本质;凡所有相,皆是虚妄。 463

Kile5报错—> ARM-Compiler ‘Default Compiler Version 5‘ which is not available安装使用Compiler Version 5 的办法

Kile5报错—> ARM-Compiler ‘Default Compiler Version 5‘ which is not available安装使用Compiler Version 5 的办法

weixin_72050316的博客 1178

【软考之软件设计师】学习笔记

interface 接口implements 实现接口(与接口配套使用)接口里要是有方法定义,子类就会实现。

云轩阁 2533

13.重量级锁原理及其实战

这篇文章深入探讨了重量级锁的核心原理及其在JVM中的实现细节。重量级锁通过监视器来保护临界区代码,确保在任何时刻只有一个线程可以进入临界区执行。文章详细解释了监视器的特点,如同步、协作、信号机制等,并介绍了在JVM中监视器是如何通过ObjectMonitor类来实现的,以及该类的关键属性和作用。其中,_cxq、_WaitSet、_EntryList等队列被用来存放等待获取监视器锁的线程,而_owner变量则记录了当前持有该监视器的线程。通过分析这些细节,读者可以更深入地理解重量级锁的工作原理和实现机制。

q1372302825的博客 1556

PINN:当深度学习遇上朗伯-比尔定律

光谱数据处理中引入PINN的三种架构设计

qq_53529450的博客 154

偏向锁,自旋锁,轻量级锁,重量锁

何为同步?JVM规范规定JVM基于进入和退出Monitor对象来实现方法同步和代码块同步,但两者的实现细节不一样。代码块同步是使用monitorenter和monitorexit指令实现,而方法同步是使用另外一种方式实现的,细节在JVM规范里并没有详细说明,但是方法的同步同样可以使用这两个指令来实现。monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到...

weixin_30919571的博客 524

基于GA-PSO-BP混合神经网络的多输入多输出数据预测-Python代码实现

多输入多输出数据预测

2301_80449389的博客 2783

基于STM32设计的智能水产养殖系统(2025)_359

本设计提出并实现了一种基于STM32F103RCT6微控制器的智能水产养殖控制系统,针对传统水产养殖中人工依赖高、环境参数监测滞后、控制手段单一等问题,集成了TDS水质检测、水温检测、水位监测、自动喂食、自动充氧、换水控制与加热保温等功能。系统采用ESP8266模块实现WIFI联网,通过MQTT协议将关键数据上传至华为云物联网平台,支持Android手机APP和Windows上位机远程监测与控制。同时,系统具备本地LCD数据显示与蜂鸣器异常报警功能,支持本地按键控制操作。整套系统功能完善,响应灵敏,运行稳定

624

Java5并发库之锁(一)

Java5并发库的锁位于java.util.concurrent.locks包,锁的作用非常类似于传统线程中的synchronizd(相关的例子可以参见http://020618.blog.51cto.com/6098149/1182775),与synchronizd相比,锁(lock)更加地面向对象,它主要用于互斥,与生活中的锁类似,锁本身也是一个对象,两个线程执行的代码片...

weixin_34343689的博客 86

【问题解决】Python 运行报错 `ModuleNotFoundError` 全网最全解决方案,一文搞定所有导包问题

本文全面解析Python中常见的ModuleNotFoundError和ImportError问题,提供从基础到高级的解决方案。文章首先分析问题原因,包括模块未安装、环境不一致、路径问题等,然后给出7种解决方案:安装缺失模块、检查Python环境、使用虚拟环境、添加搜索路径、相对导入、setup.py安装本地包和使用__init__.py。针对Jupyter Notebook、Docker容器等常见场景提供专门解决方案,并推荐使用requirements.txt、pipenv等预防措施。最后分享调试技巧,帮

博客 914

Java5种锁优化

锁优化(synchronized) JDK1.6的对锁进行了大量的优化以满足不断发展的性能要求.JDK主要的锁优化如下 自旋锁和自适应自旋锁 偏向锁 轻量级锁 锁粗化 锁消除 自旋锁和自适应自旋锁 挂起线程和恢复线程都需要转入内核态完成,这些操作给Java带来了很大的压力消耗很大,而对于大部分线程获取锁的时间很短,当一个线程等待另一个线程释放锁的时候将此线程挂起然后很短的时...

weixin_44802421的博客 336

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Java5 下实现锁无关数据结构

from:IBM developworks  本文将介绍锁无关数据结构的应用及其相关概念,并在 Java 环境下利用 JDK 1.5 提供的一组类进行锁无关数据结构设计,从而避免基于锁的数据结构可能引发的同步问题,以改善程序的可靠性。介绍 通常在一个多线程环境下,我们需要共享某些数据,但为了避免竞争条件引致数据出现不一致的情况,某些代码段需要变成原子操作去执行。这时,

leagle 1077

Statistics and Machine Learning Toolbox

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

Java—5 内建锁优化

Java—6 内建锁优化 所谓内建锁的优化就是优化线程的等待时间 ##CAS机制 1.CAS:全称 Compare And Swap 比较交换机制 CAS是一种乐观锁机制: 悲观锁:在任意时刻都有线程竞争锁,获取锁成功的线程会阻塞获取锁失败的线程成功获取锁。 乐观锁(lock):假设所有线程访问共享资源均不会发生冲突,既然不会发生冲突,就不会阻塞其他线程。不会阻塞线程 CAS(无锁操作):有...

Brain的博客 177

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java锁深入理解5——共享锁

前面无论是ReentrantLock 还是 synchronized,我们都称之为“独占锁”。其实AQS还支持另外一种锁:共享锁。说到共享锁。我首先想到的就是“读写锁”里的“读锁”,在我的认知里,共享锁就是读锁。其实也差不多,因为读写锁中动读锁就实现了AQS共享锁机制。JDK中除了读写锁ReentrantReadWriteLock之外,还有CountDownLatch。共享锁的朴素概念:有多个持用该锁的线程可以同时运行。

yunduanyou的博客 2092

5、Java中的锁

5、Java中的锁5.1 Lock接口5.2 队列同步器 介绍Java并发包中与锁相关的API和组件,以及这些API和组件的使用方式和实现 细节。内容主要围绕两个方面:使用,实现 5.1 Lock接口 锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时 访问共享资源(但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁)。 在Lock接口出现之前,Java程序是靠synchronized关键字实现锁功能的,而Java SE 5之后,并发包中新增 了Lock接口(以及相关实

北笙LBJ的博客 193

第5章 Java中的锁

5.1 Lock接口   并发编程安全性需要使用到锁,synchronized是一种隐式的获得与释放锁的关键字,除此之外还有Lock接口及其实现类,该接口及实现类提供了显示获取和释放锁的方式。   除了上述编程时的区别外,在使用时Lock与synchronized的区别主要有以下三点: 非阻塞的获取锁。一个线程在没有获得到锁的时候不是阻塞被挂起 获得锁的线程可以被中断。一个线...

weixin_30344995的博客 142

java5中的锁操作

import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * java5中的锁操作 * @author 谭飞 * @date 2012-02-03 */ public class LockTest { /** * @param args */ pu

工作博客 599

锁 唤醒_第5章 Java中的锁

5.1 Lock接口锁是用来控制多个线程访问共享资源的方式,一个锁能够防止多个线程同时访问共享资源。Java SE 5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显式地获取和释放锁。虽然它缺少了(通过synchronized块或者方法所提供的)隐式获取释放锁的便捷性,但是却拥有了锁获取与释放的可操作性、可...

weixin_33865450的博客 126

2.5java锁(synchronized,Lock,公平锁)

synchronized synchronized是Java的一个关键字,它能够将代码块(方法)锁起来 只要在代码块(方法)添加关键字synchronized,即可以实现同步 synchronized是一种互斥锁 一次只能允许一个线程进入被锁住的代码块 synchronized是一种内置锁/监视器锁 Java中每个对象都有一个内置锁(监视器,也可以理解成锁标记),而synchronized就是使用**对象的内置锁(监视器)**来将代码块(方法)锁定的! 同步代码块: monitorenter和mo

weixin_43887682的博客 1056

java并发编程(五)之 jdk5 的锁

一、锁介绍(出处:参照原文博客)1.可重入锁如果锁具备可重入性,则称作为可重入锁。像synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2...

Dason_yu的博客 365

Java synchronized锁升级机制:5步搞懂偏向锁、轻量级锁与重量级锁的转换内幕

掌握Java synchronized的锁升级机制,5步读懂偏向锁、轻量级锁到重量级锁的转换过程,涵盖适用场景与性能优势,通过日志分析深入理解底层原理。轻松解读Java synchronized的锁升级日志,值得收藏。

ProceShoal的博客 1084

java锁(5)可重入锁ReentrantLock实现详解

1、ReentrantLock的特性 ReentrantLock是Java并发包中提供的一个可重入的互斥锁。ReentrantLock和synchronized在基本用法,行为语义上都是类似的,同样都具有可重入性。只不过相比原生的Synchronized,ReentrantLock增加了一些高级的扩展功能,比如它可以实现公平锁,同时也可以绑定多个Conditon。 可重入性: 是指...

yuanwei1144的博客 148

JAVA内存模式-5-锁

从happens-before角度来看锁的释放-获取 跟volatile一样 锁的释放-获取的内存过程 跟volatile一样 如何实现锁的内存效果?? 作者这里以ReentrantLock为案例进行讲解。 Java同步器框架AbstractQueuedSynchronizer,这里暂时简称为AQS。 做讲解ReentrantLock时作者分为公平锁、非公平锁,这里我再做详解: R...

狼行千里吃肉 225
上一篇: 4. java gc
下一篇: tcp挥手,拥塞控制
big muscle
博客等级 码龄11年 145粉丝 71原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值