簡體   English   中英

Java線程安全的DAO

[英]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) 

保護您的緩沖區。

更新:

為了保護,即使在春天的緩沖,加synchronizedflushSomeTableInsertCache還有:

public synchronized int[] flushSomeTableInsertCache(String key)

實際上,您不只是使用key來標識元素。

否則,以這種方式觀察鍵沖突並不是一個好的策略,因為它們甚至可能在兩次刷新之間發生,因此您應該在數據庫中檢查它們,或者為鍵使用單獨的HashSet(如果您確定已擁有所有鍵,那里的鑰匙)。

insertBuffer是這里的唯一狀態。 在多線程環境中修改其內容可能會導致意外行為。 您可以同步對其的訪問,也可以使用ConcurrentHashMap代替HashMap

我將使用synchronized方法,而不是ConcurrentHashMap 但是,使用ConcurrentHashMap也可能會解決您的線程安全問題。

區分用法的最簡單方法是為每個線程創建一個DAOClass對象。

將您的實現更改為ConcurrentHashMap,這將解決您的並發問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM