我有服务器服务,如果满足某个标准,则会释放表数据库。看起来像这样
public static void autoUnloadDbTable(final Configuration conf) {
final String mKey = getMapKey(conf);
final Table table = TABLES.get(mKey);
if (table != null) {
dblock.getLock().lock();
table.instance.dispose();
TABLES.remove(mKey);.....(2)
}
//here release lock when done...
}
但是当执行上述功能时,还有另一个可以横向运行的操作
public Table getTableLocked(final Lock lock) throws FactFinderException {
boolean loadTable = true;
// Get the current table instance
Table table = TABLES.get(mapKey);
// .....(1)
if (table != null) {
//do something
}
if (loadTable) table = loadTableLocked(table);
// lock the table, so the instance don't gets replaced
if (lock != null) lock.lock();
return table.instance;
}
在(1)我需要放东西,因为如果一个线程在(2)执行代码而另一个线程在线程(2)已经有一个表对象但是(2)正在执行所以它将删除表对象然后超出(1)的所有内容都没有正确的值....任何建议请... ??
答案 0 :(得分:0)
根据您可以考虑包装表格的评论:
public class LockableTable {
public Table table;
public ReadWriteLock lock;
public LockableTable(Table t){
table = t;
lock = ....
}
}
然后,如果要删除表格,请执行myLocakbleTable.lock.writeLock().lock()
。当你从桌子上读书时,你可以使用myLockableTable.lock.readLock().lock()
答案 1 :(得分:0)
您可能希望在TABLES周围进行读/写锁定。在执行TABLES.get(...)以使用表中的内容之前获取读锁,并在执行TABLES.get(...)从中删除之前获取写锁。
另一种方法是每个表都有一个锁。在TABLES.get(...)获取Table特定的锁之后,确保Table仍在TABLES中,然后使用锁执行操作。此特定于表的锁也可以是读/写锁,然后只有希望删除的代码才会获得写锁。当你尝试添加到TABLES时,这会很复杂,你需要聪明,并且可能使用ConcurrentMap for TABLES,并使用putIfAbsent。
答案 2 :(得分:0)
为什么不使用ConcurrentHashMap,效率更高。
我认为您可以利用ConcurrentHashMap的锁定机制并删除您自己的锁定机制。所以 先删除第1部分:
public static void autoUnloadDbTable(final Configuration conf) {
final String mKey = getMapKey(conf);
final Table table = TABLES.remove(mKey);
if (table != null) {
table.instance.dispose();
}
}
第2节是这样的:
public Table getTableLocked(final Lock lock) throws FactFinderException {
boolean loadTable = true;
// Get the current table instance
Table table = TABLES.get(mapKey);
// .....(1)
if (table != null) {
//do something
}
if (loadTable) table = loadTableLocked(table);
return table.instance;
}
}