关于多线程的一些疑问

  最近在开发一个报表,好几个字段都是需要查好几次库来得到的,由此我想着,如果我开几个线程分别去查库,会不会快很多?这里有个并发查库会不会阻塞的问题,我也不确定,所以先放着。

  

  这让我想起了我之前写过一个逻辑,大致是先查库判断是否有记录,有则更新,无则插入。因为我写的后台并没有什么开启新的线程,所以我一直觉得,这就是个单线程的玩意儿,请求都是顺序执行,

自然也不会有什么并发问题。直到控制台总是打印,数据库插入失败,唯一键已经存在。我才发现,其实在判断通过之后,代码交由其他请求执行,并抢先一步进行了插入操作,这使得再次执行第一个请求的

时候,会提示插入失败。那么既然是个单线程的项目,应该都是顺序执行才对呀,几经百度发现其实一个请求才是一个线程。虽然我的代码里没有创建线程,但是面对前端的请求,tomcat会为其分配一个线程

执行,所以这才造成了修改同一数据的情况。修改方法也很简单,就是在让其成为同步方法即可。因为每次更新或插入前都要查记录才能确定具体的操作,和CAS很像,而这里的逻辑也是比较与更新,所以索性

就直接在方法外头加上synchronized了,(CAS的比较与更新是原子操作

 

  另外说一下synchronized的锁定范围,如果是普通方法和代码块前的this标识,锁定的是类的一个对象。如果是静态方法的synchronized或者代码块前的.class标识,则锁定该类的class对象。

区别就是,锁定类的一个实例对象的情况下,通过该对象调用任何同步方法都会同步,使用不同实例则不会同步,因为它锁定的是当前对象。锁定class类的对象后,不管创建几个实例调用同步对象都会同步。

 

posted @ 2020-07-01 18:25  菲菲一个  阅读(190)  评论(0编辑  收藏  举报