Java并发锁的悲观锁与乐观锁详解

这篇文章主要讲解了“Java并发锁的悲观锁与乐观锁详解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java并发锁的悲观锁与乐观锁详解”吧!

创新互联建站基于成都重庆香港及美国等地区分布式IDC机房数据中心构建的电信大带宽,联通大带宽,移动大带宽,多线BGP大带宽租用,是为众多客户提供专业成都服务器托管报价,主机托管价格性价比高,为金融证券行业服务器托管,ai人工智能服务器托管提供bgp线路100M独享,G口带宽及机柜租用的专业成都idc公司。

synchronized和Lock都是悲观锁,它们认为当使用数据的时候一定有其它线程来修改,所以在获取数据的时候就会加锁,确保不会被其它线程修改。

synchronized代码块:

public synchronized void update() {        //同步资源    }
 
Lock代码块:
public void update() {       Lock lock = new ReentrantLock();       lock.lock();       try {           //同步资源       } finally {           lock.unlock();       }    }
 

乐观锁,它认为使用数据的时候不会有别的线程来修改数据,所以不会加锁。只要在自身要进行update操作的时候,才会去判断之前的数据是否被别的线程修改了。如果没有被修改则会修改成功,相反则会修改不成功。这里最典型的是java.util.concurrent并发包中的递增操作就通过CAS自旋实现的。

CAS代码块

public class TestLock {        AtomicInteger atomicInteger = new AtomicInteger(0);     public int add() {        return atomicInteger.incrementAndGet();    }}
 

什么是CAS,CAS的全称为Compare And Swap(比较与交换),是一种无锁算法。在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。

Java并发锁的悲观锁与乐观锁详解

总结: 这里我们可以得出悲观锁适合写操作多的场景,先加锁可以保证写操作时数据正确。乐观锁适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升。不过从jdk1.8之后java已经对synchronized做了优化,性能上有了大幅度的提升。但是乐观锁CAS,也不是那么十全十美,目前它存在三个三大问题。

  1. ABA问题(JDK1.5之后已有解决方案):CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成了B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但是实际上是有变化的。ABA问题的解决思路就是在变量前面添加版本号,每次变量更新的时候都把版本号加一,这样变化过程就从“A-B-A”变成了“1A-2B-3A”。

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

  3. 只能保证一个共享变量的原子操作(JDK1.5之后已有解决方案):对一个共享变量执行操作时,CAS能够保证原子操作,但是对多个共享变量操作时,CAS是无法保证操作的原子性的。

感谢各位的阅读,以上就是“Java并发锁的悲观锁与乐观锁详解”的内容了,经过本文的学习后,相信大家对Java并发锁的悲观锁与乐观锁详解这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!


分享文章:Java并发锁的悲观锁与乐观锁详解
路径分享:http://ybzwz.com/article/pejgge.html