synchronized解决并发问题实践

发布时间 2023-10-08 13:50:32作者: 杨吃羊

场景一:

 场景描述:会议下面可以同时上传多个会议资料,资料是有顺序的,也就是有序号order,上传后可以上下移动资料顺序,移动资料顺序是靠改变order来实现的,这就需要保证每个资料的顺序不能一样,上传一个资料调一次上传接口,同时上传10个资料会同时调10次上传接口。上传接口逻辑是先查当前会议最大的资料order,在这个基础上自增1作为当前资料的order,再将当前资料插入到数据库。

 代码:

controller:
@RestController
public class Controller {
 @Resource
    ServiceImpl service;
@RequestMapping(value ="concurrent", method = RequestMethod.POST)
    public  void concurrent() throws InterruptedException {
        System.out.println("模拟controller业务");
        service.fun1();
    }
}

service:
@Service
public class ServiceImpl {
    @Resource
    Dao dao;
    Object lock = new Object();
    public  void fun1() throws InterruptedException {
        System.out.println("模拟service层逻辑");
        int conferenceId=1;
        int order;
        synchronized(lock){ //如果去掉这个synchronized就会出现相同的order,因为可能第一个请求查出order是2,在这个请求还没执行将3插入时,
其他请求也查出2,就会插入两次3 //查询当前会议下最大的order order = Integer.valueOf(dao.selectOrderByid(conferenceId)); Thread.sleep(100); order++; System.out.println("要插入的order为: "+order); dao.insertOder(conferenceId,order); } } }