我有一个 DAOClass,它从许多线程中调用,如下所示,用于插入到一组表中 -
public class DAOClass
{
private HashMap<String, HelperClass> insertBuffer;
public DAOClass()
{
insertBuffer = new HashMap<String, HelperClass>();
}
public int[] createSomeTable(String key, SomeTableRecord someTableRecord)
{
List<SomeTableRecord> someTableRecList;
HelperClass buf = insertBuffer.get(key);
if (buf == null)
{
buf = new HelperClass();
insertBuffer.put(key, buf);
}
someTableRecList = buf.getSomeTableBuffer();
someTableRecList.add(someTableRecord);
if(someTableRecList.size() >= Global.limit())
{
return flushSomeTableInsertCache(key);
}
else
{
return null;
}
}
public int[] flushSomeTableInsertCache(String key)
{
HelperClass buf = insertBuffer.get(key);
int[] retVal = null;
if (buf != null && buf.getSomeTableBuffer() != null)
{
retVal = createSomeTableBuffered(buf.getSomeTableBuffer());
buf.getSomeTableBuffer().clear();
}
return retVal;
}
}
public int[] createSomeTableBuffered(final List<SomeTableRecord> someTableRecordList)
{
INSERT QUERY GOES HERE from LIST..
}
}
不同的线程调用 createSomeTable 方法,该方法将添加到 HelperClass 的 ArrayList 中。有一个 HashMap,但键是重叠的,即同一个键同时被多个线程命中,从而损坏 HashMap 和不及时的刷新..
助手类如下 -
class HelperClass {
private String key;
private ArrayList<SomeTableRecord> someTableBuffer;
private ArrayList<SomeTable1Record> someTable1Buffer;
HelperClass() {
someTableBuffer = new ArrayList<SomeTableRecord>();
someTable1Buffer = new ArrayList<SomeTable1Record>();
}
public ArrayList<SomeTableRecord> getSomeTableBuffer() {
return someTableBuffer;
}
public ArrayList<SomeTable1Record> getSomeTable1Buffer() {
return someTable1Buffer;
}
}
但是,这显然不是线程安全的,因为 key 不是不相交的。您能否建议在类中进行一些更正,以便它是线程安全的。
最佳答案
您应该使用ArrayList<HelperClass>
比HashMap。为避免冲突,请使用
public synchronized int[] createSomeTable(String key, SomeTableRecord someTableRecord)
保护您的缓冲区。
更新:
要在 Spring 中保护缓冲区,请添加 synchronized
至flushSomeTableInsertCache
还有:
public synchronized int[] flushSomeTableInsertCache(String key)
实际上你没有使用key
只是为了识别元素。
否则,以这种方式观察键冲突并不是一个好的策略,因为它们甚至可能发生在两次刷新之间,因此您应该在数据库中检查它们,或者为键创建一个单独的 HashSet(如果您确定)所有 key 都在里面)。
关于Java 线程安全 DAO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14977101/