【发布时间】:2018-04-26 15:58:49
【问题描述】:
我今天在挖掘hibernate-jpa的源代码,偶然发现了以下代码sn-p(你也可以找到here):
private static class PersistenceProviderResolverPerClassLoader implements PersistenceProviderResolver {
//FIXME use a ConcurrentHashMap with weak entry
private final WeakHashMap<ClassLoader, PersistenceProviderResolver> resolvers =
new WeakHashMap<ClassLoader, PersistenceProviderResolver>();
private volatile short barrier = 1;
/**
* {@inheritDoc}
*/
public List<PersistenceProvider> getPersistenceProviders() {
ClassLoader cl = getContextualClassLoader();
if ( barrier == 1 ) {} //read barrier syncs state with other threads
PersistenceProviderResolver currentResolver = resolvers.get( cl );
if ( currentResolver == null ) {
currentResolver = new CachingPersistenceProviderResolver( cl );
resolvers.put( cl, currentResolver );
barrier = 1;
}
return currentResolver.getPersistenceProviders();
}
if ( barrier == 1 ) {} //read barrier syncs state with other threads 那个奇怪的说法让我感到不安。我花时间深入研究了volatile 关键字规范。
简单地说,在我的理解中,它确保了对相应变量的任何READ 或WRITE 操作都将始终直接在内存中通常存储值的位置执行。它专门防止通过保存该值副本的缓存或注册器进行访问,并且不一定知道该值是否已更改或正在被另一个内核上的并发线程修改。
因此,它会导致性能下降,因为每次访问都意味着要一直进入内存,而不是使用通常的(流水线?)快捷方式。但它也确保了每当线程读取变量时,它始终是最新的。
我提供这些详细信息是为了让您知道我对关键字的理解。但是现在,当我重新阅读代码时,我告诉自己“好吧,我们通过确保始终为 1 的值始终为 1(并将其设置为 1)来减慢执行速度。这有什么帮助?"
谁能解释一下?
【问题讨论】:
-
所有内存在访问 volatile 字段时被转储,搜索 SO 以找到 Java 规范的链接
-
哦,我忘记在问题中写了。那么这有什么帮助呢?
-
您的非易失性字段也将同步
-
不,那不是“JPA 的源代码”。这是 HIBERNATE 的 JPA 实现中的一些代码。其他 JPA 提供者不这样做
标签: java multithreading hibernate jpa volatile