Java 线程安全 DAO

标签 java multithreading 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;
}
}

但是,这显然不是线程安全的,因为 key 不是不相交的。您能否建议在类中进行一些更正,以便它是线程安全的。

最佳答案

您应该使用ArrayList<HelperClass>比HashMap。为避免冲突,请使用

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

保护您的缓冲区。

更新:

要在 Spring 中保护缓冲区,请添加 synchronizedflushSomeTableInsertCache还有:

public synchronized int[] flushSomeTableInsertCache(String key)

实际上你没有使用key只是为了识别元素。

否则,以这种方式观察键冲突并不是一个好的策略,因为它们甚至可能发生在两次刷新之间,因此您应该在数据库中检查它们,或者为键创建一个单独的 HashSet(如果您确定)所有 key 都在里面)。

关于Java 线程安全 DAO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14977101/

相关文章:

java - 在 Struts 2 中使用拦截器时出现 NullPointerException

django - 具有 1 个线程的 django 如何可以提供并发访问?

excel - 在 Excel 中显示 MS-Access 记录的富文本格式

java - EasyMock 和 Ibatis

Java EE : Where could I read about dao, 服务以及为什么使用它们?

java - 找不到从哪里获取 Spring xml 命名空间条目

java - 为什么重新启动具有限制 UserManager.DISALLOW_USB_FILE_TRANSFER 使用的应用程序的设备会导致该设备无法使用?

java - SwingWorker 完成后挂起 : Is it bad practise to start and run a thread pool from a SwingWorker?

c++ - "thread-safe"函数并行化框架是否依赖?

java - 使用 Java 将给定日期的时间与两个给定时间字符串进行比较