[英]Java thread safe DAO
我有一個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;
}
}
但是,這顯然不是線程安全的,因為密鑰不是不相交的。 您能否建議在類中進行一些更正,以便它是線程安全的。
請改用ConcurrentHashMap類。
您應該寧願使用ArrayList<HelperClass>
不是HashMap。 為避免沖突,請使用
public synchronized int[] createSomeTable(String key, SomeTableRecord someTableRecord)
保護您的緩沖區。
更新:
為了保護,即使在春天的緩沖,加synchronized
到flushSomeTableInsertCache
還有:
public synchronized int[] flushSomeTableInsertCache(String key)
實際上,您不只是使用key
來標識元素。
否則,以這種方式觀察鍵沖突並不是一個好的策略,因為它們甚至可能在兩次刷新之間發生,因此您應該在數據庫中檢查它們,或者為鍵使用單獨的HashSet(如果您確定已擁有所有鍵,那里的鑰匙)。
insertBuffer
是這里的唯一狀態。 在多線程環境中修改其內容可能會導致意外行為。 您可以同步對其的訪問,也可以使用ConcurrentHashMap
代替HashMap
。
我將使用synchronized
方法,而不是ConcurrentHashMap
。 但是,使用ConcurrentHashMap
也可能會解決您的線程安全問題。
區分用法的最簡單方法是為每個線程創建一個DAOClass
對象。
將您的實現更改為ConcurrentHashMap,這將解決您的並發問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.