简体   繁体   English

Java线程安全的DAO

[英]Java thread safe DAO

I have a DAOClass which is called from many Threads as below for inserting into a set of tables - 我有一个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 call createSomeTable method which adds to an ArrayList of a HelperClass. 不同的线程调用createSomeTable方法,该方法将添加到HelperClass的ArrayList中。 There is a HashMap but the key is overlapping ie same key is hit by multiple threads simultaneously, thus corrupting HashMap and untimely flushings .. 有一个HashMap,但是键是重叠的,即同一键同时被多个线程击中,从而损坏了HashMap和不合时宜的冲洗。

Helper Class follows - 助手类如下-

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;
}
}

But, this is apparently not thread safe as key is not disjoint. 但是,这显然不是线程安全的,因为密钥不是不相交的。 Can you please suggest some correction in the classes so that it is thread safe. 您能否建议在类中进行一些更正,以便它是线程安全的。

请改用ConcurrentHashMap类。

You should rather use ArrayList<HelperClass> than HashMap. 您应该宁愿使用ArrayList<HelperClass>不是HashMap。 To avoid conflicts, use 为避免冲突,请使用

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

to protect your buffer. 保护您的缓冲区。

UPDATE: 更新:

To protect the buffer even in Spring, add synchronized to flushSomeTableInsertCache as well: 为了保护,即使在春天的缓冲,加synchronizedflushSomeTableInsertCache还有:

public synchronized int[] flushSomeTableInsertCache(String key)

Actually you don't use key s just to identify the elements. 实际上,您不只是使用key来标识元素。

Otherwise it is not a good strategy to watch key collisions this way, because they can even happen between 2 flushes, so you should either check them in the database, or have a separate HashSet for the keys (if you are sure that you have all the keys in there). 否则,以这种方式观察键冲突并不是一个好的策略,因为它们甚至可能在两次刷新之间发生,因此您应该在数据库中检查它们,或者为键使用单独的HashSet(如果您确定已拥有所有键,那里的钥匙)。

insertBuffer is the only state here. insertBuffer是这里的唯一状态。 Modifying its content in a multi-threaded environment might result in unexpected behavior. 在多线程环境中修改其内容可能会导致意外行为。 You can either synchronize access to it or use ConcurrentHashMap instead of HashMap . 您可以同步对其的访问,也可以使用ConcurrentHashMap代替HashMap

I would use synchronized methods rather than ConcurrentHashMap . 我将使用synchronized方法,而不是ConcurrentHashMap However, using ConcurrentHashMap might solve your thread-safe-issue as well. 但是,使用ConcurrentHashMap也可能会解决您的线程安全问题。

区分用法的最简单方法是为每个线程创建一个DAOClass对象。

将您的实现更改为ConcurrentHashMap,这将解决您的并发问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM