我有一个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..
}
}
Different Threads调用createSomeTable方法,该方法添加到HelperClass的ArrayList。有一个HashMap但是密钥是重叠的,即同一个密钥同时被多个线程命中,从而破坏了HashMap和不合时宜的冲突。
Helper Class如下 -
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;
}
}
但是,这显然不是线程安全的,因为密钥不是不相交的。你能否在课程中提出一些修正,以便它是线程安全的。
答案 0 :(得分:0)
改为使用ConcurrentHashMap类。
答案 1 :(得分:0)
您应该使用ArrayList<HelperClass>
而不是HashMap。为避免冲突,请使用
public synchronized int[] createSomeTable(String key, SomeTableRecord someTableRecord)
保护你的缓冲区。
<强>更新强>
即使在Spring中也要保护缓冲区,同时将synchronized
添加到flushSomeTableInsertCache
:
public synchronized int[] flushSomeTableInsertCache(String key)
实际上,您不仅仅使用key
来识别元素。
否则以这种方式观察键冲突不是一个好的策略,因为它们甚至可以在2次刷新之间发生,所以你应该在数据库中检查它们,或者为键提供单独的HashSet(如果你确定你有所有的钥匙。)
答案 2 :(得分:0)
insertBuffer
是这里唯一的州。在多线程环境中修改其内容可能会导致意外行为。您可以同步对其的访问权限,也可以使用ConcurrentHashMap
代替HashMap
。
答案 3 :(得分:0)
我会使用synchronized
方法而不是ConcurrentHashMap
。但是,使用ConcurrentHashMap
也可以解决您的线程安全问题。
答案 4 :(得分:0)
分离用法的最简单方法是为每个线程创建一个DAOClass
对象。
答案 5 :(得分:0)
将您的实现更改为ConcurrentHashMap,这将解决您的并发问题。