悲观锁和乐观锁

  •  悲观锁

    悲观,则会假设情况总是最坏的,即共同维护的数据总会被其他线程修改,所以每次取数据的时候都会上锁,避免其他人修改。

  • synchronized 关键字的实现也是悲观锁。

  • 悲观锁的缺点

    • 在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。

    • 一个线程持有锁会导致其它所有需要此锁的线程挂起。

    • 如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。

 synchronized 锁的形式

public static void main(String[] args) {MyThread t1 = new MyThread("窗口一");MyThread t2 = new MyThread("窗口二");t1.start();t2.start();
}//错误情况
@Overridepublic void run() {while(count > 0) {System.out.println(Thread.currentThread().getName()+"售出:"+(count--) +" 票");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
//静态代码块上锁
@Overridepublic void run() {while(count > 0) {//静态代码块锁,定义同一个对象synchronized (obj) {System.out.println(Thread.currentThread().getName()+"售出:"+(count--) +" 票");}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}//方法上锁public synchronized void increse() {System.out.println(Thread.currentThread().getName()+"售出:"+(count--) +" 票");}@Overridepublic void run() {while(count > 0) {increse();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
//类上锁
synchronized(类名.Class) { //允许访问控制的代码 
}

  • 乐观锁

  • 乐观,则假设情况总是最好的,即共同维护的数据不会被其他线程修改,所以不会上锁(即无锁)。
  • CAS(Compare and Swap)
  • 非阻塞性,不存在死锁问题。没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销,具有更优越的性能。
  • 算法过程
  • 包含三个参数 CVS(V,E,N)。V表示要更新的变量,E表示预期值,N表示新值。仅当 V 值等于 E 值时,才会将 V 的值设为 N ,如果 V 值与 E 值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。最后, CAS 返回当前 V 的真实值。当多个线程同时使用 CAS 操作一个变量时,只有一个会胜出,并成功更新,其余均会失败。失败的线程不会挂起而是允许再次尝试。
  •  lock锁

  • Lock 只是一个顶层抽象接口,并没有实现,也没有规定是乐观锁还是悲观锁实现规则。 ReentrantLock ,ReentrantReadWriteLock 。
  • ReentrantLock()

    ReentrantLock() 干了啥

    public ReentrantLock() {sync = new NonfairSync();}


    在lock的构造函数中,定义了一个NonFairSync,

    static final class NonfairSync extends Sync

    NonfairSync 又是继承于Sync

    abstract static class Sync extends AbstractQueuedSynchronizer

  • lock的存储结构:一个int类型状态值(用于锁的状态变更),一个双向链表(用于存储等待中的线程)
  • lock获取锁的过程:本质上是通过CAS来获取状态值修改,如果当场没获取到,会将该线程放在线程等待链表中。
  • lock释放锁的过程:修改状态值,调整等待链表。

 ReentrantReadWriterLock 通过两个内部类实现 Lock 接口,分别是 ReadLock,WriterLock 类。它表示两个锁,一个是读操作相关的锁,称为共享锁;一个是写相关的锁,称为排他锁,描述如下:

线程进入读锁的前提条件:
没有其他线程的写锁,
没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。

线程进入写锁的前提条件:
没有其他线程的读锁
没有其他线程的写锁

一、synchronized和lock的用法区别

synchronized:在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象。
lock:需要显示指定起始位置和终止位置。一般使用ReentrantLock类做为锁,多个线程中必须要使用一个ReentrantLock类做为对象才能保证锁的生效。且在加锁和解锁处需要通过lock()和unlock()显示指出。所以一般会在finally块中写unlock()以防死锁。lock只能写在代码里,不能直接修改方法。

二、synchronized和lock性能区别
synchronized是托管给JVM执行的,而lock是java写的控制锁的代码。
Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。
Java1.6中,synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。
性能不一样:资源竞争激励的情况下,lock性能会比synchronize好,竞争不激励的情况下,synchronize比lock性能好,synchronize会根据锁的竞争情况,从偏向锁-->轻量级锁-->重量级锁升级,而且编程更简单。
锁机制不一样:synchronize是在JVM层面实现的,系统会监控锁的释放与否。lock是JDK代码实现的,需要手动释放,在finally块中释放。可以采用非阻塞的方式获取锁。
Synchronized的编程更简洁,lock的功能更多更灵活,缺点是一定要在finally里面 unlock()资源才行。
其他区别:
1,首先二者的关键字不同,sync是关键字,lock是接口。

2,sync会主动释放锁,lock不会,而且容易产生死锁。

3,sync默认是非公平锁,悲观锁。Lock用的是乐观锁方式,乐观锁实现的机制就是CAS操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322278.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sentinel(九)之热点参数限流

转载自 热点参数限流 Overview 何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如: 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制用户 …

jzoj3318-[BOI2013]Brunhilda的生日【数论】

正题 题目大意 序列aaa有mmm个质数。然后询问一个数nnn,每次可以使nn−n%ainn-n\%a_{i}nn−n%ai​ 求最少操作次数。 解题思路 首先我们设fif_ifi​表示由iii变为0的最少次数,然后有动态转移fimin{fi−i%aj}1f_imin\{f_{i-i\%a_j}\}1fi​min{fi−i%aj​…

【直播 】ASP.NET Core解密底层设计逻辑

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

Sentinel(十)之系统自适应限流

转载自 系统自适应限流 Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平…

jzoj3319-[BOI2013]雪地踪迹【bfs】

正题 题目大意 一个n∗mn*mn∗m的雪地,有两种动物RRR和FFF会在雪地上留下RRR和FFF的脚印(只可以走到相邻格子,从(1,1)(1,1)(1,1)进入(n,m)(n,m)(n,m)出来,且会覆盖掉原先的脚印)。 求至少有多少只动物经过 解题思路 首先我们知道(1,1)(1,1…

如何ASP.NET Core Razor中处理Ajax请求

在ASP.NET Core Razor(以下简称Razor)刚出来的时候,看了一下官方的文档,一直没怎么用过。今天闲来无事,准备用Rozor做个项目熟练下,结果写第一个页面就卡住了。。折腾半天才搞好,下面给大家分享下解决方案。先来给大家简单介绍下RazorRazor Pages是ASP.NET Core的一项新功能&am…

Sentinel(十一)之黑白名单控制

转载自 黑白名单控制 很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通…

Loj2687,jzoj3320-文本编辑器【线头dp】

正题 题目链接:https://loj.ac/problem/2687 题目大意 三个操作: hhh光标向前移动一格xxx删除光标处字母fcf\ cf c移动到下一个字符ccc(算两次操作) 然后fff操作不能对字符eee使用,然后求最少操作次数删除所有的eee。 解题思路 线头dpdpdp。 设fi,jf_{i,j}fi,j​…

小白带你入坑xamarin系列之环境搭建和准备

序言:移动端的跨平台百花齐放,各种技术方案和方法都是层出不穷。目前xamarin确实是一套成熟可靠,完全值得信赖的开发框架。尤其是对传统做WPF ASP.NET的开发团队来说要节约成本开始移动端开发。这个是很好的一个选项。开始之前回答2个问题。1…

P3402-[模板]可持久化并查集【主席树】

正题 题目链接:https://www.luogu.org/problemnew/show/P3402 题目大意 合并x,yx,yx,y所在的两个集合回到操作kkk之后询问x,yx,yx,y是否在同一个集合 解题思路 正常的并查集,不使用路径压缩,但是使用按秩合并,将深度小的合并到深度大的上面…

Sentinel(十二)之实时监控

转载自 实时监控 Sentinel 提供对所有资源的实时监控。如果需要实时监控&#xff0c;客户端需引入以下依赖&#xff08;以 Maven 为例&#xff09;&#xff1a; <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-transport-sim…

Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本

Dora.Interception 1.0&#xff08;可以访问GitHub地址&#xff1a;https://github.com/jiangjinnan/Dora&#xff09;推出有一段时间了&#xff0c;最近花了点时间将它升级到2.0&#xff0c;主要有如下的改进&#xff1a;提供了原生的动态代理生成底层框架Dora.DynamicProxy&a…

欢乐纪中某A组赛【2019.7.8】

前言 你以为我是jzojjzojjzoj&#xff0c;其实我是GMojGMojGMoj哒 成绩 JJJ表示初中&#xff0c;HHH表示高中后面加的是几年级 上至222分XJQXJQXJQ,下至200ZZY200ZZY200ZZY都有我们SSLSSLSSL的人(滑稽) |RankRankRank|PersonPersonPerson|ScoreScoreScore|AAA|BBB|CCC| RankR…

Sentinel(十四)之控制台

转载自 Sentinel 控制台 1. 概述 Sentinel 提供一个轻量级的开源控制台&#xff0c;它提供机器发现以及健康情况管理、监控&#xff08;单机和集群&#xff09;&#xff0c;规则管理和推送的功能。这里&#xff0c;我们将会详细讲述如何通过简单的步骤就可以使用这些功能。 …

C# 这些年来受欢迎的特性

原文地址:http://www.dotnetcurry.com/csharp/1411/csharp-favorite-features在写这篇文章的时候&#xff0c;C# 已经有了 17 年的历史了&#xff0c;可以肯定地说它并没有去任何地方。C# 语言团队不断致力于开发新特性&#xff0c;改善开发人员的体验。在这篇文章中&#xff0…

P2657-[SCOI2009]windy数【数位dp,dfs】

正题 题目链接:https://www.luogu.org/problemnew/show/P2657 题目大意 求A∼BA\sim BA∼B中不含前导零且没两个相邻的位数相差至少为222的数字个数。 解题思路 考虑记忆化搜索&#xff0c;用fi,jf_{i,j}fi,j​表示到第iii位数字为jjj时的方案数。 然后用1∼B1\sim B1∼B中…

Sentinel(十三)之动态规则扩展

转载自 动态规则扩展 规则 Sentinel 的理念是开发者只需要关注资源的定义&#xff0c;当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则&#xff1a; 通过 API 直接修改 (loadRules)通过 DataSource 适配不同数据源修改 手动通过 API 修改比较…

AspectCore动态代理中的拦截器详解(一)

前言在上一篇文章使用AspectCore动态代理中&#xff0c;简单说明了AspectCore.DynamicProxy的使用方式&#xff0c;由于介绍的比较浅显&#xff0c;也有不少同学留言询问拦截器的配置&#xff0c;那么在这篇文章中&#xff0c;我们来详细看一下AspectCore中的拦截器使用。两种配…

P3279-[SCOI2013]密码【Manacher】

正题 题目链接:https://www.luogu.org/problemnew/show/P3279 题目大意 一个字符串满足: 有nnn个字符仅包含小写字母告诉你每个字符为中心的最大回文串长度告诉你每个两个字符的间隙为中心的最大回文串长度 求满足要求的字典序最小的字符串。 解题思路 因为字典序最小&…

Actor-ES框架:Ray

并发1. 并发和并行并发&#xff1a;两个或多个任务在同一时间段内运行。关注点在任务分割。并行&#xff1a;两个或多个任务在同一时刻同时运行。关注点在同时执行。本文大多数情况下不会严格区分这两个概念&#xff0c;默认并发就是指并行机制下的并发。2. 好处随着多核处理器…