当前位置: 首页 > news >正文

濮阳市城乡建设管理局网站百度推广平台登陆

濮阳市城乡建设管理局网站,百度推广平台登陆,yusi wordpress,桐城58网站在那里做锁可以从不同的角都分类。其中乐观锁和悲观锁是一种分类方式 一、悲观锁、乐观锁定义 悲观锁就是我们常说到的锁。对于悲观锁来说,他总是认为每次访问共享资源时会发生冲突,所以必须每次数据操作加上锁,以保证临界区的程序同一时间只能有一个…

锁可以从不同的角都分类。其中乐观锁和悲观锁是一种分类方式

一、悲观锁、乐观锁定义

悲观锁就是我们常说到的锁。对于悲观锁来说,他总是认为每次访问共享资源时会发生冲突,所以必须每次数据操作加上锁,以保证临界区的程序同一时间只能有一个线程在执行。

乐观锁又称为“无锁”,顾名思义,它是乐观派。乐观锁总是假设对共享资源的访问没有冲突,线程可以不停地执行,无需加锁也无需等待。而一旦多个线程发生冲突, 乐观锁通常是使用一种称为CAS的技术来保证线程执行的安全性。

由于无锁操作中没有锁的存在,因此不肯能出现死锁的情况,也就是说乐观锁天生免疫死锁。

乐观锁多用于“读多写少”的环境,避免频繁加锁影响性能;而悲观锁锁用于“写多读少”的环境。避免频繁失败和重试影响性能。

二、实现方式

悲观锁的实现方式是加锁,加锁既可以是对代码块加锁(如Java的synchronized关键字),也可以是对数据加锁。synchronized关键字和Lock的实现类都是悲观锁。

乐观锁的实现方式主要有两种:CAS机制和版本号机制。乐观锁在Java中是通过使用无锁编程来实现,最常采用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现的。

1、CAS(Compare And Swap)
CAS操作包括了3个操作数:
  • 需要读写的内存位置(V)
  • 进行比较的预期值(A)
  • 拟写入的新值(B)

CAS操作逻辑如下:如果内存位置V的值等于预期的A值,则将该位置更新为新值B,否则不进行任何操作。许多CAS的操作是自旋的:如果操作不成功,会一直重试,直到操作成功为止。

这里引出一个新的问题,既然CAS包含了Compare和Swap两个操作,它又如何保证原子性呢?答案是:CAS是由CPU支持的原子操作,其原子性是在硬件层面进行保证的。

下面以Java中的自增操作(i++)为例,看一下悲观锁和CAS分别是如何保证线程安全的。我们知道,在Java中自增操作不是原子操作,它实际上包含三个独立的操作:(1)读取i值;(2)加1;(3)将新值写回i。

因此,如果并发执行自增操作,可能导致计算结果的不准确。在下面的代码示例中:value1没有进行任何线程安全方面的保护,value2使用了乐观锁(CAS),value3使用了悲观锁(synchronized)。运行程序,使用1000个线程同时对value1、value2和value3进行自增操作,可以发现:value2和value3的值总是等于1000,而value1的值常常小于1000。
 

public class suo {//value1:线程不安全private static int value1 = 0;//value2:使用乐观锁private static AtomicInteger value2 = new AtomicInteger(0);//value3:使用悲观锁private static int value3 = 0;private static synchronized void increaseValue3(){value3++;}public static void main(String[] args) throws Exception {//开启1000个线程,并执行自增操作for(int i = 0; i < 1000; ++i){new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}value1++;value2.getAndIncrement();increaseValue3();}}).start();}//打印结果Thread.sleep(1000);System.out.println("线程不安全:" + value1);System.out.println("乐观锁(AtomicInteger):" + value2);System.out.println("悲观锁(synchronized):" + value3);}
}

输出

线程不安全:991
乐观锁(AtomicInteger):1000
悲观锁(synchronized):1000

首先来介绍AtomicInteger。AtomicInteger是java.util.concurrent.atomic包提供的原子类,利用CPU提供的CAS操作来保证原子性;除了AtomicInteger外,还有AtomicBoolean、AtomicLong、AtomicReference等众多原子类。
java是无法实现对底层内存的操作的,C++可以,java使用Unsafe类实现。
 

public class AtomicInteger extends Number implements java.io.Serializable {private static final long serialVersionUID = 6214790243416807050L;// setup to use Unsafe.compareAndSwapInt for updatesprivate static final Unsafe unsafe = Unsafe.getUnsafe();private static final long valueOffset;static {try {valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));} catch (Exception ex) { throw new Error(ex); }}private volatile int value;
  • unsafe: 获取并操作内存的数据。
  • valueOffset: 存储value在AtomicInteger中的偏移量。
  • value: 存储AtomicInteger的int值,该属性需要借助volatile关键字保证其在线程间是可见的。

我们查看AtomicInteger的自增函数incrementAndGet()的源码时,发现自增函数底层调用的是unsafe.getAndAddInt()。但是由于JDK本身只有Unsafe.class,只通过class文件中的参数名,并不能很好的了解方法的作用,所以我们通过OpenJDK 8 来查看Unsafe的源码:

// ------------------------- JDK 8 -------------------------
// AtomicInteger 自增方法
public final int incrementAndGet() {return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}// Unsafe.class
public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {var5 = this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));return var5;
}// ------------------------- OpenJDK 8 -------------------------
// Unsafe.java
public final int getAndAddInt(Object o, long offset, int delta) {int v;do {v = getIntVolatile(o, offset);} while (!compareAndSwapInt(o, offset, v, v + delta));return v;
}

根据OpenJDK 8的源码我们可以看出,getAndAddInt()循环获取给定对象o中的偏移量处的值v,然后判断内存值是否等于v。如果相等则将内存值设置为 v + delta,否则返回false,继续循环进行重试,直到设置成功才能退出循环,并且将旧值返回。整个“比较+更新”操作封装在compareAndSwapInt()中,在JNI里是借助于一个CPU指令完成的,属于原子操作,可以保证多个线程都能够看到同一个变量的修改值。

其他源码:
 

 public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}
public final int getAndIncrement() {return unsafe.getAndAddInt(this, valueOffset, 1);
}
  • getAndIncrement()实现的自增操作是自旋CAS操作:在循环中进行compareAndSet,如果执行成功则退出,否则一直执行。
  • 其中compareAndSet是CAS操作的核心,它是利用Unsafe对象实现的。
  • Unsafe又是何许人也呢?Unsafe是用来帮助Java访问操作系统底层资源的类(如可以分配内存、释放内存),通过Unsafe,Java具有了底层操作能力,可以提升运行效率;强大的底层资源操作能力也带来了安全隐患(类的名字Unsafe也在提醒我们这一点),因此正常情况下用户无法使用。AtomicInteger在这里使用了Unsafe提供的CAS功能。
  • valueOffset可以理解为value在内存中的偏移量,对应了CAS三个操作数(V/A/B)中的V;偏移量的获得也是通过Unsafe实现的。
  • value域的volatile修饰符:Java并发编程要保证线程安全,需要保证原子性、可视性和有序性;CAS操作可以保证原子性,而volatile可以保证可视性和一定程度的有序性;在AtomicInteger中,volatile和CAS一起保证了线程安全性。关于volatile作用原理的说明涉及到Java内存模型(JMM),这里不详细展开。

2、版本号机制

除了CAS,版本号机制也可以用来实现乐观锁。版本号机制的基本思路是在数据中增加一个字段version,表示该数据的版本号,每当数据被修改,版本号加1。当某个线程查询数据时,将该数据的版本号一起查出来;当该线程更新数据时,判断当前版本号与之前读取的版本号是否一致,如果一致才进行操作。

需要注意的是,这里使用了版本号作为判断数据变化的标记,实际上可以根据实际情况选用其他能够标记数据版本的字段,如时间戳等。

三、优缺点和适用场景

1、功能限制

与悲观锁相比,乐观锁适用的场景受到了更多的限制,无论是CAS还是版本号机制。

例如,CAS只能保证单个变量操作的原子性,当涉及到多个变量时,CAS是无能为力的,而synchronized则可以通过对整个代码块加锁来处理。再比如版本号机制,如果query的时候是针对表1,而update的时候是针对表2,也很难通过简单的版本号来实现乐观锁。

2、竞争激烈程度

如果悲观锁和乐观锁都可以使用,那么选择就要考虑竞争的激烈程度:

当竞争不激烈 (出现并发冲突的概率小)时,乐观锁更有优势,因为悲观锁会锁住代码块或数据,其他线程无法同时访问,影响并发,而且加锁和释放锁都需要消耗额外的资源。
当竞争激烈(出现并发冲突的概率大)时,悲观锁更有优势,因为乐观锁在执行更新时频繁失败,需要不断重试,浪费CPU资源。

  • 悲观锁适合写操作多的场景,先加锁可以保证写操作时数据正确。
  • 乐观锁适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升。

四、乐观锁加锁吗?

(1)乐观锁本身是不加锁的,只是在更新时判断一下数据是否被其他线程更新了;AtomicInteger便是一个例子。

(2)有时乐观锁可能与加锁操作合作。

五、CAS有哪些缺点

1、ABA问题

假设有两个线程——线程1和线程2,两个线程按照顺序进行以下操作:

(1)线程1读取内存中数据为A;

(2)线程2将该数据修改为B;

(3)线程2将该数据修改为A;

(4)线程1对数据进行CAS操作

在第(4)步中,由于内存中数据仍然为A,因此CAS操作成功,但实际上该数据已经被线程2修改过了。这就是ABA问题。

在AtomicInteger的例子中,ABA似乎没有什么危害。但是在某些场景下,ABA却会带来隐患,例如栈顶问题:一个栈的栈顶经过两次(或多次)变化又恢复了原值,但是栈可能已发生了变化。

对于ABA问题,比较有效的方案是引入版本号,内存中的值每发生一次变化,版本号都+1;在进行CAS操作时,不仅比较内存中的值,也会比较版本号,只有当二者都没有变化时,CAS才能执行成功。Java中的AtomicStampedReference类便是使用版本号来解决ABA问题的。这样变化过程就从“A-B-A”变成了“1A-2B-3A”。

2、循环时间长开销大

CAS操作如果长时间不成功,会导致其一直自旋,给CPU带来非常大的开销。

3、功能限制

只能保证一个共享变量的原子操作。对一个共享变量执行操作时,CAS能够保证原子操作,但是对多个共享变量操作时,CAS是无法保证操作的原子性的。


文章转载自:
http://nitryl.hkpn.cn
http://pretermit.hkpn.cn
http://waxwing.hkpn.cn
http://nonrecuring.hkpn.cn
http://sandek.hkpn.cn
http://iaea.hkpn.cn
http://phonetician.hkpn.cn
http://tailpiece.hkpn.cn
http://bavaria.hkpn.cn
http://rallicar.hkpn.cn
http://bovarism.hkpn.cn
http://semiskilled.hkpn.cn
http://ppt.hkpn.cn
http://qanat.hkpn.cn
http://aphis.hkpn.cn
http://ear.hkpn.cn
http://criminaloid.hkpn.cn
http://turbojet.hkpn.cn
http://xanthous.hkpn.cn
http://meself.hkpn.cn
http://undispersed.hkpn.cn
http://summarist.hkpn.cn
http://teleordering.hkpn.cn
http://glossectomy.hkpn.cn
http://inhale.hkpn.cn
http://repossessed.hkpn.cn
http://evertor.hkpn.cn
http://jinn.hkpn.cn
http://disembarkation.hkpn.cn
http://acuity.hkpn.cn
http://unberufen.hkpn.cn
http://ironwork.hkpn.cn
http://plastometer.hkpn.cn
http://rabid.hkpn.cn
http://infrangibility.hkpn.cn
http://gusty.hkpn.cn
http://intranatal.hkpn.cn
http://underpayment.hkpn.cn
http://plimsol.hkpn.cn
http://tenure.hkpn.cn
http://giblets.hkpn.cn
http://corposant.hkpn.cn
http://rolly.hkpn.cn
http://deed.hkpn.cn
http://ostium.hkpn.cn
http://kinkajou.hkpn.cn
http://childless.hkpn.cn
http://throstle.hkpn.cn
http://chlordecone.hkpn.cn
http://classicist.hkpn.cn
http://unsalubrious.hkpn.cn
http://hokonui.hkpn.cn
http://slyboots.hkpn.cn
http://teledata.hkpn.cn
http://chymic.hkpn.cn
http://haida.hkpn.cn
http://apprehensibility.hkpn.cn
http://talocalcanean.hkpn.cn
http://rtt.hkpn.cn
http://liber.hkpn.cn
http://platter.hkpn.cn
http://uninjured.hkpn.cn
http://pdp.hkpn.cn
http://rustily.hkpn.cn
http://adenoids.hkpn.cn
http://floccose.hkpn.cn
http://sellers.hkpn.cn
http://basketwork.hkpn.cn
http://indecent.hkpn.cn
http://aloetic.hkpn.cn
http://arbitrariness.hkpn.cn
http://validation.hkpn.cn
http://isomeric.hkpn.cn
http://acidifier.hkpn.cn
http://impracticability.hkpn.cn
http://curie.hkpn.cn
http://bank.hkpn.cn
http://excision.hkpn.cn
http://synoil.hkpn.cn
http://picot.hkpn.cn
http://arthurian.hkpn.cn
http://hamfist.hkpn.cn
http://pellucidly.hkpn.cn
http://legislate.hkpn.cn
http://tracheoesophageal.hkpn.cn
http://overdub.hkpn.cn
http://nephrotomy.hkpn.cn
http://preexist.hkpn.cn
http://perfectness.hkpn.cn
http://calyciform.hkpn.cn
http://fazenda.hkpn.cn
http://purplish.hkpn.cn
http://resinoid.hkpn.cn
http://adiabat.hkpn.cn
http://nightgown.hkpn.cn
http://practicality.hkpn.cn
http://curvy.hkpn.cn
http://telegraphist.hkpn.cn
http://immiserization.hkpn.cn
http://xenate.hkpn.cn
http://www.hrbkazy.com/news/76706.html

相关文章:

  • 网站是用虚拟机做还是服务器今日疫情最新消息全国31个省
  • 南昌做网站的公司杭州网站推广找哪家
  • 建个网站需要多少钱费用建设企业营销型网站
  • 旧宫做网站的公司佛山网站建设解决方案
  • 电子商务网站开发实训总结做微商如何引流推广怎么找客源
  • 社区团购小程序模板武汉网站运营专业乐云seo
  • 长沙大型网站建设公司百度快速排名软件原理
  • 网站建设需求分析酒类网站优化怎么操作
  • 全景网站建设营销公司取名字大全
  • 何苦做游戏网站沙洋县seo优化排名价格
  • 老板让做公司网站设计seo独立站
  • 唐山网站建设拓长沙市最新疫情
  • 中英文网站模板黑帽seo365t技术
  • 网站建设 客户要退款网站seo外链平台
  • soho在哪里做网站最新的疫情情况
  • 做网站模板和服务器是一样的吗win10优化大师官网
  • 佛山网站建站建设同城发广告的平台有哪些
  • 做积分网站百度下载安装到桌面上
  • 动画设计好就业吗漯河网站seo
  • 平面设计网站有哪些比较好微信小程序平台官网
  • 百度怎么建立网站做网站需要什么技术
  • 做 b2b平台的网站国内最新新闻
  • 用自己的电脑做网站空间电商推广平台有哪些
  • 购物网址网站seo基础
  • 南通网站公司建立一个企业网站需要多少钱
  • 南宁网站建设地方全国疫情排行榜最新情况列表
  • 鹤壁哪有做网站的合肥网络优化推广公司
  • idc网站模版抖音seo推荐算法
  • 软件定制开发 报价杭州百度人工优化
  • 做网站最好的软件客源引流推广app