并发编程基础四

本文介绍了并发编程中锁的几种类型,包括悲观锁、乐观锁、公平锁与非公平锁、独占锁和共享锁。悲观锁认为数据容易被修改,所以在访问前加锁;乐观锁则在数据更新时检查冲突。此外,文章还提到了可重入锁与自旋锁,可重入锁允许线程多次获取已持有的锁,自旋锁则在未获取锁时消耗CPU资源等待。
摘要由CSDN通过智能技术生成

锁的概述

1.1 乐观锁与悲观锁

悲观锁指对数据被外界修改持保守态度,认为数据很容易就会被其他线程修改,所以在数据被处理前先对数据进行加锁,并在整个数据处理过程中,使数据处于锁定状态。悲观锁的实现往往依靠数据库提供的锁机制,即在数据库中,在对数据记录操作前给记录加排它锁。如果获取锁失败,则说明数据正在被其线程修改,当前线程则等待或者抛出异常。如果获取锁成功,则对记录进行操作,然后提交事务后释放排它锁。

下面我们看一个典型的例子,看它如何使用悲观锁来避免多线程同时对一个记录进行修改。

Public int update(long id){
//1.使用悲观锁获取指定记录
EntryObject entry=query(“select * from table1 where id=#{id} for update”,id);

//2.修改记录内容,根据计算修改entry记录的属性
String name=generatorName(entry);
Entry.setName(name);

//3.udpate操作
int count =update(“update table1 set name=#{name},age=#{age} where id=#{id}”,entry);
return count;
}

对于如上代码,假设updateEntry、query、update方法都使用了事务切面的方法,并且事务传播性被设置为required。执行updateEntry方法时,如果上层调用方法里面没有开启事务,则会即时开启一个事务,然后执行代码1。代码1调用了query方法,其根据指定id从数据库里面查询出一个记录。由于事务传播性为required,所以执行query时没有开启新的事务,而是加入了updateEntry开启的事务,也就是在updateEntry方法执行完毕提交事务时,query方法才会被提交,就是说记录的锁定会持续到updateEntry执行结束。2则对获取的记录进行修改,代码3把修改的内容写回数据库,同样代码3的update法也没有开启新的事务,而是加入了updateEntry的事务。也就是updateEntry、query、update方法共用同一事务。当多个线程同时调用updateEntry方法,并且传递的是同一个id时,只有一线程执行代码1会成功,其他线程则会被阻塞,这是因为在同时间只有一个线程可以获取对应记录的锁,在获取锁的线程释放锁前(updateEntry执行毕,提交事务前),其他线程必须等待,也就是在一时间只有一个线程可以对该记录进行修改。乐观锁是相对悲观锁来说的,它认为数在一般情况不会造成冲突,所以在访问记录前不会加排它锁,而是进行数据提交更新时,才会正式对数据冲突与否进行检测。具体来说,根据update返回的行数让用户决定如何去做。将上面的例子改为使用乐观锁的代码如下。

    publicintupdateEntry(longid){
    //(1)使用乐观锁获取指定记录
    EntryObject entry=query(”select * from tablel whereid=#{id}”,id);
    //(2)修改记录内容,version字段不能被修改
    String name=generatorName(entry);
    entry.setName(name);
    //(3)update操作
    int count=update(“update tablel set name=#{name},age=#{age},version=${version}+1 where                     
    id=#{id} and version=#{version)”,entry);
    return count;
    }

在如上代码中,当多个线程调用updateEntry方法并且传递相同的id时,多个线程可以同时执行代码1获取id

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值