正如标题所述,我正试图排除一些从Singleton读取数据的线程获得空值的问题。我对我们日志的调查看上去好像是一个并发问题。
Singleton的定义如下:
@Singleton
public class StaticDatabaseEntries {
private static final Map<String,Thing> databaseEntries = new HashMap<>();
@Lock(LockType.READ)
public Thing getThing(String index) {
return databaseEntries.get(index);
}
}起初,我的印象是,当对同一项的访问重复返回null时,数据中只有一个元素被破坏。对调试条目的进一步访问表明,该问题似乎与特定线程隔离。似乎一旦发生了什么,导致线程上的空返回继续这样做,但只在受影响的线程上。
这个类的早期版本没有应用LockType.READ,因此根据规范假定是LockType.WRITE。我部署了一个具有正确锁的更新,以启用并发读取。这并没有改善情况。
数据在部署时从数据库加载到HashMap,并且在部署期间保持不变。由于类没有使用@Startup标记,所以应用程序使用上下文侦听器来触发从数据库加载条目。
对于主要执行读取活动的线程,我不认为切换到ConcurrentHashMap是有益的。我正在考虑删除static final部分,因为当容器管理并发访问和单例生命周期时,这似乎是不必要的。当容器不能在EJB中标记为final的子类/代理事物时,我遇到了副作用。
我考虑过的另一种可能性是容器软件中存在某种形式的bug。这是在较旧的Java1.7和JBoss6EAP上运行的。最糟糕的情况是,我必须放弃单例模式,而是按需从数据库加载条目。
发布于 2021-12-21 17:42:50
一般情况下:如果您使用线程,读取活动可能会导致问题,如果您正在调用一个对象方法,那不是线程保存!这正是导致大型项目中无法检测到的错误的原因。
HashMap不是线程安全的!
您应该切换到ConcurrentHashMap。
有关详细信息,请参阅本文:https://www.baeldung.com/java-concurrent-map
https://stackoverflow.com/questions/70438919
复制相似问题