1

テーブルのセットに挿入するために、以下のように多くのスレッドから呼び出される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..
}
}

異なるスレッドは、HelperClass の ArrayList に追加する createSomeTable メソッドを呼び出します。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;
}
}

しかし、キーがバラバラではないため、これは明らかにスレッドセーフではありません。スレッドセーフになるようにクラスの修正を提案してください。

4

6 に答える 6

0

代わりにクラスConcurrentHashMapを使用してください。

于 2013-02-20T10:08:05.257 に答える
0

用途を分ける最も簡単な方法は、DAOClassスレッドごとに 1 つのオブジェクトを作成することです。

于 2013-02-20T10:25:16.140 に答える
0

ArrayList<HelperClass>HashMap よりも使用する必要があります。競合を避けるには、

public synchronized int[] createSomeTable(String key, SomeTableRecord someTableRecord) 

バッファを保護します。

アップデート:

Spring でもバッファを保護するには、次のように追加synchronizedflushSomeTableInsertCacheます。

public synchronized int[] flushSomeTableInsertCache(String key)

実際にはkey、要素を識別するためだけに s を使用するわけではありません。

それ以外の場合、この方法でキーの衝突を監視するのは適切な戦略ではありません。なぜなら、衝突は 2 つのフラッシュの間に発生する可能性があるためです。そのため、データベースで確認するか、キー用に個別の HashSet を用意する必要があります (すべてのキーが確実にある場合)。鍵はそこにあります)。

于 2013-02-20T10:13:55.017 に答える
0

insertBuffer州はここだけです。マルチスレッド環境でそのコンテンツを変更すると、予期しない動作が発生する可能性があります。アクセスを同期するか、ConcurrentHashMap代わりに を使用できますHashMap

于 2013-02-20T10:16:01.640 に答える
0

実装を ConcurrentHashMap に変更すると、同時実行の問題が解決されます。

于 2013-02-20T12:24:59.827 に答える
0

synchronizedではなくメソッドを使用しますConcurrentHashMap。ただし、を使用ConcurrentHashMapすると、スレッドセーフの問題も解決される場合があります。

于 2013-02-20T10:24:50.313 に答える