锁定问题:需要一些头脑风暴建议

时间:2011-03-24 12:40:57

标签: java multithreading thread-safety

我有服务器服务,如果满足某个标准,则会释放表数据库。看起来像这样

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)的所有内容都没有正确的值....任何建议请... ??

3 个答案:

答案 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;
}

}