公平锁,非公平锁,乐观锁,悲观锁

公平锁/非公平锁(多线程执行顺序的维度)

概念理解

  • 公平锁:加锁前先查看是否有排队等待的线程,有的话优先处理排在前面的线程,先来先得
  • 非公平所:线程加锁时直接尝试获取锁,获取不到就自动到队尾等待。

例子

  • ReentrantLock 同时支持两种锁
//创建一个非公平锁,默认是非公平锁

Lock nonFairLock= new ReentrantLock();

Lock nonFairLock= new ReentrantLock(false);

//创建一个公平锁,构造传参true

Lock fairLock= new ReentrantLock(true);

适用场景

  • 更多的是直接使用非公平锁:非公平锁比公平锁性能高5-10倍,因为公平锁需要在多核情况下维护一个队列,如果当前线程不是队列的第一个无法获取锁,增加了线程切换次数。

乐观锁/悲观锁(多线程操作共享数据的维度)

概念理解

  • 悲观锁:假设一定会发生并发冲突,通过阻塞其他所有线程来保证数据的完整性。
  • 乐观锁:假设不会发生并发冲突,直接不加锁去完成某项更新,如果冲突就返回失败。

例子

  • 悲观锁:Synchronized多线程同步,具有排他性,也会容易产生死锁。
  • 乐观锁:CAS机制,简单来说会有三个操作数,当前内存变量值V,变量预期值A,即将更新值B,当需要更新变量的时候,会直接将变量值V和预期值A进行比较,如果相同,则直接更新为B;如果不相同,则当前变量值V刷新到预期值中,然后重新尝试比较更新。

适用场景

  • 乐观锁:适用于数据争用不严重/重试代价不大/需要相应速度快的场景。
  • 悲观锁:适用于数据争用严重/重试代价大的场景。

原文地址:https://www.cnblogs.com/darrenqiao/p/9211178.html

时间: 2024-10-27 05:47:47

公平锁,非公平锁,乐观锁,悲观锁的相关文章

最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 01.乐观锁 vs 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制. 乐观锁适用于多

【多线程】公平锁/非公平锁、乐观锁/悲观锁

公平锁/非公平锁(多线程执行顺序的维度) 概念理解 公平锁:加锁前先查看是否有排队等待的线程,有的话优先处理排在前面的线程,先来先得. 非公平所:线程加锁时直接尝试获取锁,获取不到就自动到队尾等待. 例子 ReentrantLock 同时支持两种锁 //创建一个非公平锁,默认是非公平锁 Lock nonFairLock= new ReentrantLock(); Lock nonFairLock= new ReentrantLock(false); //创建一个公平锁,构造传参true Lock

锁的公平与非公平

锁是给线程用的,线程拿到锁之后才能干活.当多个线程竞争一个锁时,同一个时间只能有一个线程脱颖而出持有锁,其他线程等该线程释放锁后发起下一轮竞争.那么这种竞争就存在公平性问题,如果是公平的竞争,那么这些线程就得有序来依次得到锁,这就需要线程们按先来后到排队,第一个线程使用完后把锁递给第二个线程,以此类推.非公平的锁是无序的,举个例子:线程甲持有锁,后面线程乙跑过来争,发现被甲拿了就去睡觉(休眠或者被挂起)了,等线程甲释放锁通知乙来取:过了会儿,乙被唤醒时,刚好线程丙半路杀过来了,把锁拿去用了,而乙

java ReentrantLock 公平锁 非公平锁 测试

1 package reentrantlock; 2 3 import java.util.ArrayList; 4 import java.util.concurrent.locks.ReentrantLock; 5 6 public class TestFairSyn { 7 8 public static void main(String[] args) { 9 ArrayList<Thread> arrayList = new ArrayList<>(); 10 Resrc

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

获取非公平锁(基于JDK1.7.0_40) 非公平锁和公平锁在获取锁的方法上,流程是一样的:它们的区别主要表现在"尝试获取锁的机制不同".简单点说,"公平锁"在每次尝试获取锁时,都是采用公平策略(根据等待队列依次排序等待):而"非公平锁"在每次尝试获取锁时,都是采用的非公平策略(无视等待队列,直接尝试获取锁,如果锁是空闲的,即可获取状态,则获取锁).在前面的"Java多线程系列--"JUC锁"03之 公平锁(一)&q

并发编程总结5-JUC-REENTRANTLOCK-3(非公平锁)

非公平锁和公平锁在获取锁的方法上,流程是一样的:区别主要表现在“尝试获取锁的机制不同”.“公平锁”在每次尝试获取锁时,都是采用公平策略(根据等待队列依次排序等待):而“非公平锁”在每次尝试获取锁时,都是采用的非公平策略(无视等待队列,直接尝试获取锁,如果锁是空闲的,即可获取状态,则获取锁). 一.获取非公平锁 lock() NonfairSync类中实现 final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThre

AQS实现公平锁和非公平锁

基于AQS的锁(比如ReentrantLock)原理大体是这样:有一个state变量,初始值为0,假设当前线程为A,每当A获取一次锁,status++. 释放一次,status--.锁会记录当前持有的线程.当A线程拥有锁的时候,status>0. B线程尝试获取锁的时候会对这个status有一个CAS(0,1)的操作,尝试几次失败后就挂起线程,进入一个等待队列.如果A线程恰好释放,--status==0, A线程会去唤醒等待队列中第一个线程,即刚刚进入等待队列的B线程,B线程被唤醒之后回去检查这

Java多线程编程4--Lock的使用--公平锁和非公平锁

公平与非公平锁:锁Lock分为"公平锁"和"非公平锁",公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即先来先得的FIFO先进先出顺序.而非公平锁就是一种获取锁的抢占机制,是随机获得锁的,和公平锁不一样的就是先来的不一定先得到锁,这个方式可能造成某些线程一直拿不到锁,结果也就是不公平的了. 1.公平锁实例 public class Service { private ReentrantLock lock ; public Service(boolean i

多线程学习 公平锁和非公平锁

公平与非公平锁:锁lock分为 公平锁和非公平锁,公平锁表示现场获取锁的顺序是按照线程加锁的顺序来分配的, 即先来先得的FIFO先进先出顺序.而非公平锁就是一种获取锁的抢占机制,是随机获得的锁的,和公平锁不一样的就是先来 不一定先得到锁,这个方式可能造成某些线程一直拿不到锁. 首先来验证公平锁:创建service方法,使用lock进行锁定. public class Service { private ReentrantLock lock; public Service(boolean isFa