我之前写过一段代码,它从jar文件中动态加载类。 因此,基本上可以在123-de目录中存在a.jar,在456-fg目录中存在另一个a.jar。现在,根据某些参数,我决定使用哪个jar,并从123-de目录或456-fg目录加载一个类说calc.java。
为此,我必须创建类加载器并使用这些类加载器来加载calc.java
当然,每个jar应该有一个类加载器,每个类在内存中加载单个类。
为此,我使用了一个存储类加载器/类的并发hashmap。 说这个并发hashmap的关键是目录名。
所以,给定一个目录,我检查是否已经存在类加载器 - 如果不是我在一个上创建然后存储它。
if(classLoaderMap.get(directoryPath) == null){
rlock.lock();
try{
if(classLoaderMap.get(directoryPath) == null){
ClassLoader classLoader = // Create classLoader here.
classLoaderMap.put(directoryPath, classLoader);
}
}finally{
rlock.unlock();
}
}
此代码经过测试且运行正常。但今天我正在重新审视这段代码,并观察到我并不真正需要concurrenthashmap,因为我使用显式锁定来写入它。我只需要内存可见性,因为我在锁外读它。所以,我真的在想volatile hashmap
是否已完成这项工作?我应该还原它(不要因为它已经测试过了)或者如果我保留它可以吗?
答案 0 :(得分:5)
您是否正在访问其他地方的classLoaderMap
以从中读取值?如果是,您还需要在那里使用相同的锁,以确保内存可见性。
volatile
在这种情况下无济于事,因为它只会确保变量classLoaderMap
的值的更新对其他线程可见,而不是对其他线程的内容可见地图本身。
我仍然建议在这种情况下使用ConcurrentHashMap
,这样就不需要显式锁定,并确保地图的内容的内存可见性。
使用Java 8,使用ConcurrentHashMap
:
classLoaderMap.computeIfAbsent(directoryPath, (path) -> createClassLoader(path));
答案 1 :(得分:4)
不,使用常规地图是不安全的,因为您需要锁定读取和写入。一种选择是使用grouped = df.groupby('Date').apply(lambda x: x['Value'].cummax() \
.drop_duplicates()) \
.reset_index()
print(df[df.index.isin(grouped['level_1'])])
Date Time Value
0 2000-01-01 09:00:00 2
2 2000-01-01 17:00:00 3
3 2000-01-02 09:00:00 2
4 2000-01-02 13:00:00 3
6 2000-01-03 09:00:00 1
9 2000-01-04 09:00:00 3
,因此您可以支持非独占读取,而写入仍然是读写独占的。另一种选择(可能是更好的选择)是坚持ReadWriteLock
并摆脱锁定。至于如何以原子方式更新的问题,只需使用原子ConcurrentHashMap
方法:
computeIfAbsent()