Synchronized 同步出现失效

Synchronized 同步出现失效

Synchronized ,大家都知道这个是Java 提供的一种原子性内置锁,其实现原理是通过获取对象的监视器monitor进行来实现同步的,只有当线程获取到对象monitor才能继续执行,否则该线程进行阻塞(等待)。

示例:

public class DemoServiceImpl {  

    @Autowired    
    private DemoDao demoDao;    
    
    // 根据id获取序列号,获取完之后进行 + 1        
    @Transactional    
    public synchronized String getSn(Long id) {
           DemoSn sn = demoDao.getSnById(id);       
           sn.setSn(sn.getSn() + 1);       
           demoDao.update(sn);         
           return sn.getSn().toString();    
    }    
 }

描述一下代码示例: 该方法涉及++ 1 ,当如果多个线程进行调用该方法时,会出现数据安全性问题,所以我在这里进行加了 Synchronized, 保证该方法的每次执行只能允许一个线程进来。

本以为这里加了 Synchronized, 就是线程安全了,但是经过测试之后发现,这里同步锁并没有起作用,多个线程进行调用该方法时,还是出现返回的 值重复。

Synchronized 失效原因:
先简单介绍一下Spring @Transactional执行原理: @Transactional 注解是Spring 提供来进行控制事务的注解,当注解标明在方法上时, 则会对 该方法进行做AOP 增强(动态代理),然后在方法执行前,开启事务,执行后提交事务。

如果上述示例方法只添加了 Synchronized, 并没有标明@Transactional, 因为加了同步锁,所以getSn() 一次只能允许一个线程进入, 执行过程:

A(线程): DemoServiceImpl#getSn() > B(线程): DemoServiceImpl#getSn()

如果上述示例方法添加了 Synchronized,并标明@Transactional 线程的执行过程:

A(线程): Spring begins transactional > DemoServiceImpl#getSn() > Spring commits transactional
B(线程): Spring begins transactional > DemoServiceImpl#getSn() > Spring commits transactional 

这里看着是没有问题

开启事务 -> 执行方法体 -> 提交事务

但是这里也恰恰是出现**Synchronized** 失效的关键

Synchronized 失效关键原因:是因为**Synchronized**锁定的是当前调用方法对象,而Spring AOP 处理事务会进行生成一个代理对象,并在代理对象执行方法前的事务开启,方法执行完的事务提交,所以说,事务的开启和提交并不是在 Synchronized 锁定的范围内。出现同步锁失效的原因是:当A(线程) 执行完getSn()方法,会进行释放同步锁,去做提交事务,但在A(线程)还没有提交完事务之前,B(线程)进行执行getSn() 方法,执行完毕之后和A(线程)一起提交事务, 这时候就会出现线程安全问题。

synchronized关键字的失效可能有多种原因。其中一种情况是,在多线程环境下,当使用了不同的锁对象,即每个线程持有不同的锁对象时,synchronized关键字就会失效。这是因为synchronized关键字是基于对象的monitor锁来实现同步的,如果每个线程都拥有不同的锁对象,那么它们之间就无法进行同步。 另一种情况是,当对一个非静态方法使用synchronized关键字时,每个线程调用的是不同的对象实例的方法,那么synchronized关键字也会失效。这是因为非静态方法是基于对象实例的锁来实现同步的,如果每个线程调用的是不同的对象实例的方法,那么它们之间也无法进行同步。 此外,还有可能存在其他原因导致synchronized关键字失效,比如在使用synchronized关键字时出现了异常或错误的使用方式。因此,当synchronized关键字失效时,需要仔细检查代码逻辑和使用方式,确保正确地使用了同步机制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Synchronized-锁失效问题剖析](https://blog.csdn.net/weixin_45987569/article/details/127725420)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值