互联网面试Java中的锁都有哪些?
在平时工作开发中难免会被多线程操作共享资源相关的问题所困扰,这个时候我们一般来解决这个问题的方式就是通过锁机制来保证线程操作的安全性。在Java中我们经常使用到的锁就是Synchroinzed,JVM的关键字,它是依赖于JVM系统调用来实现锁操作。ReentrantLock,是在Java并发包下的基于AQS实现的一种可重入锁机制,其原理就是采用CAS来修改一个被volatile关键字修饰的int类型数据来标识对象是否获取到了锁,如果state变量值不为零则证明当前有线程正在使用该锁。
关于锁的概念,其实并不是Java独有的概念,在很多的场景中都会有多线程访问共享的资源的操作,我们可以根据不同的规则将锁进行分类。下面我们就来谈谈在Java中的锁的规则与分类都有哪些?根据是否有对其他线程操作有影响来划分
乐观锁
所谓的乐观锁就是默认认为在当前线程去修改数据的情况下,不会有其他线程来进行数据的修改,也就是说在数据的操作过程中是不需要对其进行加锁的。CAS(比较并交换)是乐观锁的最佳实践,也就是需要比较内存中的实际值与期待得到的值是否相同,如果相同了才会更新,其底层实现是利用cmpxchg指令来实现。有兴趣的读者可以研究一下CPU中的cmpxchg指令。
悲观锁
顾名思义,也就是默认会认为在当前线程修改数据的时候,一定会有其他的线程对数据进行修改,也就是说在操作共享数据之前必须要对所要操作的数据先进行加锁操作。在Java中的Synchroinzed和ReentrantLock都是悲观锁的实现。根据对获取不到锁的线程的处理情况来划分
轻量级锁
所谓的轻量级锁是指如果当前锁已经被某个线程所持有了,如果当前线程获取不到锁的时候,那么就会自旋等待,等到锁释放之后在进行获取当前锁。也就是说在获取到锁之前,线程一直是处于自旋等待。
重量级锁
而所谓的重量级锁是指,如果锁被某个线程持有了,当前线程如果获取不到锁,就会将当前线程挂起来等待锁的释放,或者是线程被唤醒的过程。
从这里可以看出如果使用了重量级锁那么一个线程在获取不到锁的时候就会挂起等待,而这个过程需要进行CPU的线程上下文切换,而这个切换时间远远大于用户执行代码本身的时间,所以对于一般耗时较短的任务可以采用轻量级锁来让线程进行自旋等待,会省去了不少上下文切换的时间。
从上面的描述中我们也知道,如果使用了轻量级锁,在整个线程持有锁的执行过程中,如果线程自旋等待的时间太长,就会导致资源的浪费,这样就引入了一个概念,就是锁升级,锁粗化,这些操作都是用来对锁进行优化的。一般来讲锁升级是从无锁到偏向锁,再到轻量级锁,再到重量级锁。每个过程都是结合实际来对锁进行处理,有效的解决了因为锁使用不当带来的系统资源消耗等问题。
上面所提到的无锁,就是不加锁,共享资源被所有线程共同访问,一般来讲CAS的方式就是一种无锁实现。
偏向锁则是指如果当前线程获取到了锁,在执行过程中也没有其他线程来与之竞争锁,那么这个锁就会偏向于当前持有线程的获取,在当前线程再次执行的时候就不需要在进行获取锁的操作了,这样做的好处就是再一定程度上减少了获取锁所带来的线程开销。
在之前的分享中我们介绍过关于Synchroinzed的相关原理,有兴趣的读者可以到合集中去查看。根据线程竞争锁获取规则的设计来进行划分
公平锁
公平锁,是指如果当前线程已经获取到了锁,并且还未完成操作,其他线程如果想要获取到该锁,那么就必须排队等待。
非公平锁
非公平锁,是指如果当前线程已经获取到锁除了,那么新的线程如果想要获取到锁,那么就需要通过CAS操作来抢一下锁,如果抢到了,就执行逻辑,如果抢不到了再去排队等待执行。
在JDK中对于ReentrantLock的操作就是支持公平与非公平的,默认情况下是非公平的。代码如下 /** * Sync object for non-fair locks */ static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; /** * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }
如果线程想要获取到锁,那么需要去修改private volatile int state,对应的值。也就是通过compareAndSetState(0, 1)方法来抢一下锁,然后通过setExclusiveOwnerThread(Thread.currentThread()),操作来执行锁如果抢不到则执行acquire(1)操作。
公平锁的实现代码如下。在获取锁的时候就只进行了acquire(1)操作。 /** * Sync object for fair locks */ static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; final void lock() { acquire(1); } /** * Fair version of tryAcquire. Don"t grant access unless * recursive call or no waiters or is first. */ 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; } }锁重入机制
重入锁和非重入锁
所谓的重入锁,就是当前线程获取到锁的时候,如果这个线程再次进入获取锁的时候可以直接进入而不需要重新获取锁的操作。在Java中的Synchroinzed和ReentrantLock都是可重入锁。而非重入顾名思义就是当前线程如果再次执行同步代码块的时候还需要再次等待获取锁。锁共享机制
独占锁和共享锁
独占锁的概念就是说如果有一个线程获取到锁,那么其他线程则不能继续获取该锁,也就是说这个锁是对于这个线程来讲是独有的。
共享锁则是指一个锁可以有多个线程来共同获取,也就是一个线程获取到该锁之后,其他线程还可以继续获取到该锁。
上面我们提到的基于AQS实现的ReentrantLock就是独占锁。而AQS也是提供了共享锁的操作方案tryAcquireShared,Semaphore就是通过tryAcquireShared来实现的共享操作。
图片来源网格
河源移动助力公安精准打击GOIP电话诈骗随着断卡行动的持续深入,传统电话卡作案呈现大幅下降态势,诈骗分子逐步转向利用其他非法技术手段实施诈骗,其中伪基站2。0简易GOIP固话猫等新诈骗技术不断出现,藏匿在境外的电信网络诈
当996的我,工资还没父母退休金高,买房生娃都得啃老延迟退休话题下,人们不仅忧虑工作时间再度延长,也忧虑未来拿不到退休金。而在当下,一部分年轻人发现,父辈们的退休金比自己的工资还高,退休金倒挂的现象越来越多。中青年在社会上内卷,退休
非遗少年学优秀案例乡村非遗根脉厚,花灯瑶绣焕生机2022年广东省非遗少年学优秀案例征集活动获奖名单日前正式放榜,共评出优秀传承学校10家优秀传承单位10家优秀乡村传承学校10家及优秀传承人10人。本届活动由广东省文化和旅游厅广东
在家门口搭建帐篷,我国试点城市公园绿地开放共享住房和城乡建设部近日发布通知,我国将开展城市公园绿地开放共享试点,鼓励各地增加可进入可体验的活动场地,完善配套服务设施。记者在上海广东湖北等地采访发现,部分城市此前已探索城市公园绿
为上合示范区聚势赋能,总投资118亿元项目集中签约2月17日,百家科创企业和百名高层次人才上合行少海国际科创专场活动在胶州绿城喜来登酒店举行。中国科学院院士施剑林等40位专家和企业家齐聚上合新区,共商科技创新和产业发展大计。中铁北
智慧城市数据可视化平台辅助城市管理者决策智慧城市发展到一定阶段的产物,是在互联网大数据和云计算等新一代信息技术支撑下,通过建设高效的政务信息化系统智能交通系统和智慧安全保障系统,以及配套的创新应用和社会民生服务体系,以实
北向资金大幅加仓股名单2月16日,北向资金净买入67。94亿元,其中,深股通净买入37。79亿元,沪股通净买入30。15亿元。证券时报数据宝统计显示,2月16日共有732只股持股量环比上一个交易日增加,
中关村顺义园13个重点项目全面复工北京日报客户端记者王可心通讯员肖亦为人勤春早,实干正当时。2月17日,记者从顺义区获悉,中关村顺义园内13个项目建设工地全部复工,高精尖产业结构加速构建,为全年经济发展起好步开好局
国军起义将领中,级别最高的三人有谁?估计老蒋很痛心解放战争,大家都知道,开战初期,共产党的军队武器比较简陋兵力也不足,而国民党的军队不但有着现代化的武器装备,还有着充足而庞大的兵力,国民党的官员从上到下也对战况非常乐观,很多人认为
辛弃疾的命运悲剧是儒化弱宋的写照辛弃疾(11401207),原字坦夫,改字幼安,别号稼轩居士,历城(今山东济南)人。辛弃疾出生前十三年,宋室遭逢靖康之乱,中原被金人占领。辛弃疾祖父辛赞为家计所累,未能脱身南下,曾
2000多年前,西周王室的财路有多广?除了帝京内的收入,还有这些诗经魏风说硕鼠硕鼠,无食我黍!三岁贯女,莫我肯顾。逝将去女,适彼乐土。前面看似是在谴责大老鼠偷吃农人种的粮食,后面却说如此辛勤伺候你,你却半点不照料我,那我就要离开了。如此来看,这