Java并发编程(05):悲观锁和乐观锁机制 (2)

悲观锁本身的实现机制就以损失性能为代价,多线程争抢,加锁、释放锁会导致比较多的上下文切换和调度延时,加锁的机制会产生额外的开销,还有增加产生死锁的概率,引发性能问题。

乐观锁虽然会基于对比检测的手段判断更新的数据是否有变化,但是不确定数据是否变化完成,例如线程1读取的数据是A1,但是线程2操作A1的值变化为A2,然后再次变化为A1,这样线程1的任务是没有感知的。

悲观锁每一次数据修改都要上锁,效率低,写数据失败的概率比较低,比较适合用在写多读少场景。

乐观锁并未真正加锁,效率高,写数据失败的概率比较高,容易发生业务形异常,比较适合用在读多写少场景。

是选择牺牲性能,还是追求效率,要根据业务场景判断,这种选择需要依赖经验判断,不过随着技术迭代,数据库的效率提升,集群模式的出现,性能和效率还是可以两全的。

三、Lock基础案例 1、Lock方法说明

lock:执行一次获取锁,获取后立即返回;

lockInterruptibly:在获取锁的过程中可以中断;

tryLock:尝试非阻塞获取锁,可以设置超时时间,如果获取成功返回true,有利于线程的状态监控;

unlock:释放锁,清理线程状态;

newCondition:获取等待通知组件,和当前锁绑定;

2、应用案例 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockThread02 { public static void main(String[] args) { LockNum lockNum = new LockNum() ; LockThread lockThread1 = new LockThread(lockNum,"TH1"); LockThread lockThread2 = new LockThread(lockNum,"TH2"); LockThread lockThread3 = new LockThread(lockNum,"TH3"); lockThread1.start(); lockThread2.start(); lockThread3.start(); } } class LockNum { private Lock lock = new ReentrantLock() ; public void getNum (){ lock.lock(); try { for (int i = 0 ; i < 3 ; i++){ System.out.println("ThreadName:"+Thread.currentThread().getName()+";i="+i); } } finally { lock.unlock(); } } } class LockThread extends Thread { private LockNum lockNum ; public LockThread (LockNum lockNum,String name){ this.lockNum = lockNum ; super.setName(name); } @Override public void run() { lockNum.getNum(); } }

这里多线程基于Lock锁机制,分别依次执行任务,这是Lock的基础用法,各种API的详解,下次再说。

3、与synchronized对比

基于synchronized实现的锁机制,安全性很高,但是一旦线程失败,直接抛出异常,没有清理线程状态的机会。显式的使用Lock语法,可以在finally语句中最终释放锁,维护相对正常的线程状态,在获取锁的过程中,可以尝试获取,或者尝试获取锁一段时间。

四、源代码地址 GitHub·地址 https://github.com/cicadasmile/java-base-parent GitEE·地址 https://gitee.com/cicadasmile/java-base-parent

Java并发编程(05):悲观锁和乐观锁机制

推荐阅读:Java基础系列

序号 文章标题
A01   Java基础:基本数据类型,核心点整理  
A02   Java基础:特殊的String类,和相关扩展API  
B01   Java并发:线程的创建方式,状态周期管理  
B02   Java并发:线程核心机制,基础概念扩展  
B03   Java并发:多线程并发访问,同步控制  
B04   Java并发:线程间通信,等待/通知机制  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsjpy.html