记一次队友并发中的线程安全问题

hibernate 多线程update·死锁(locked timeout)
描述:
hibernate+spring+springmvc 配置了openSessionInView,先查询,查询后的结果集交给另一个线程更新字段, 少量数据正常,大量数据时死锁。
问题:关键是hibernate查询出来的结果集是数据库实体,队友没有将实体转化成bo,在主线程中修改了实体中的字段;交给新线程更新实体数据集后,由于主线程中修改了实体的字段,导致数据被加锁,主线程由于数据量较大导致事务没有及时提交,子线程中同时请求了数据的行锁,导致锁超时。本身是由代码的bug造成的,用bo阻断可以解决或者把修改任务都交给子线程即可解决。
原子类并发set非线程安全
错误代码

AtomicInteger i = new AtomicInteger(0);
        List<Integer> list = Collections.synchronizedList(new ArrayList<>(100));
        for(int num=0;num<1000;num++){
            list.add(num);
        }
        list.parallelStream().forEach(nu->{
            i.compareAndSet(i.get(),i.get()+2);
        });
        System.out.println(i.get());

问题就出在 i.compareAndSet(i.get(),i.get()+2);中的i.get()上,在并行时可能会在某几个线程中获取到的i的值相同而导致线程安全问题。
解决思路是吧对i的操作转变为原子操作 i.getAndAdd(2);交由UNSAFE类去做判断。
修改后

AtomicInteger i = new AtomicInteger(0);
        List<Integer> list = Collections.synchronizedList(new ArrayList<>(100));
        for (int num = 0; num < 1000; num++) {
            list.add(num);
        }
        list.parallelStream().forEach(nu -> {
            i.getAndAdd(2);
        });
        System.out.println(i.get());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值