service中的成员变量,是否存在线程安全问题?
场景如下,我想在一个service中定义一个map,用于存储设备的最新记录,key为设备id,value为最新record_id。
并且这个service中定义了一个定时器,用来定时查询最新的记录,并装入这个map。如果想要查询设备的最新记录则先看看这个map里的key存不存在要查询的设备id
如果这个map为非线程安全的类,如HashMap,请问以下条件是否有线程安全
问题1:如果其他方法只对这个map进行读取,只由springBoot提供的定时注解方法去更新这个map,那么是否会存在线程安全问题?
问题2:如果其他方法读取了这个map发现key里不存在要查找的设备id,则去查找数据库,并且将得到的结果写入到这个map中,这样是否线程安全?
回答:
问题1:安全,因为不涉及并发写
问题2:不安全,因为设计并发写,多个线程同时写同一个HashMap会出问题
回答:
如果使用非线程安全的HashMap实现该map,则存在线程安全问题。
对于问题1,如果只有一个线程写入该map,其他线程只读取该map,则不会存在线程安全问题。但是,如果同时有多个线程读取和写入该map,则可能会出现并发问题,比如多个线程同时写入同一个key,可能导致数据的覆盖或丢失。
对于问题2,如果在写入数据时没有进行同步控制,则可能会出现线程安全问题。例如,如果多个线程同时尝试写入同一个key,则可能会出现数据的覆盖或丢失。
为了确保线程安全,可以使用线程安全的Map实现,例如ConcurrentHashMap。或者,在对HashMap进行读写操作时,需要进行同步控制,例如使用synchronized关键字对Map进行加锁。
回答:
问题1,安全。之前项目中也是这么玩的,HashMap就行。定时更新里面的数据,其他的只读。
问题2,并发写当然不安全。
其实再深一层思考的话,假如现在多个线程都同时查询到map里面没有这个key。接下来,大家都去读库然后写map。
这不就类似缓存击穿
么,这时需要考虑的问题:
- ①理论上只需要一个线程读库即可,现在变成多个了。是否考虑加锁,让一个线程去读库即可?
②当他们都读完后,写map时安全的吗?
- 代码层的安全:HashMap在1.7时并发写可能出现死循环问题,后续没问题
- 业务层的安全:脏数据?被覆盖?好像不会有问题
另外,单纯的使用ConcurrentHashMap
只是保证了map本身的安全。多个线程同时读库,这个问题还是没有解决。
另外有个putIfAbsent
可以保证只写一次map,其他线程的读库变得没有意义了。
以上是 service中的成员变量,是否存在线程安全问题? 的全部内容, 来源链接: utcz.com/p/945089.html