尝试从中检索时ConcurrentHashMap的线程安全问题

时间:2013-02-13 00:40:41

标签: java multithreading concurrency concurrenthashmap

我正在尝试在单个线程中为每个具有不同JDBC URL's的数据库建立新连接。

在我的下面的代码段中,tableNames是地图,其中包含表格的名称以及要连接到它们的属性。含义table1 will be in different databasetable2 will be in different database

tableNames地图的示例示例 -

{table1={DRIVER=oracle.jdbc.driver.OracleDriver, PASSWORD=stage_cs_user, URL=jdbc_url, SUFFIX=xt1, SQL=sql, USER=user}, table2={DRIVER=driver_name, PASSWORD=pass, URL=jdbc_url2, SUFFIX=xt2, SQL=sql2, USER=user}}

以下是我的代码 -

class Task implements Runnable {

    private Connection[] dbConnection = null;
    private CallableStatement[] callableStatement = null;

    private final ArrayList<Method> methods[] = null;
    private final ConcurrentHashMap<String, ConcurrentHashMap<String, String>> tableLists;

    public Task(ConcurrentHashMap<String, ConcurrentHashMap<String, String>> tableNames) {
        this.tableLists = tableNames;
    }

    @Override
    public void run() {

        try {

        int i=0;
        for (Map<String, String> map : tableLists.values()) {
            dbConnection[i] = getDBConnection(map.get("URL"), map.get("USER"), map.get("PASSWORD"), map.get("DRIVER"));
            callableStatement[i] = dbConnection[i].prepareCall(map.get("SQL"));

            methods[i] = getRequiredMethods(map.get("SUFFIX"));
            i++;
                    }
                }   
             }
       }

在查看此代码时,它并不认为它是一个线程安全的代码。

我相信这里存在线程安全问题,因为多个线程将从tableLists Map获取。有什么方法可以让这个线程安全吗?

所以我的问题是ConcurrentHashMap从它检索数据时线程安全吗?有没有什么方法可以让这个线程在这里保持安全并稍微提高一点?

更新了代码并提供了更多详细信息: -

class Task implements Runnable {

    private Connection[] dbConnection = null;
    private CallableStatement[] callableStatement = null;

    private final ArrayList<Method> methods[] = null;
    private final ConcurrentHashMap<String, ConcurrentHashMap<String, String>> tableLists;

    public Task(ConcurrentHashMap<String, ConcurrentHashMap<String, String>> tableNames) {
        this.tableLists = tableNames;
    }

@Override
public void run() {

    try {

        int j=0;
        dbConnection = new Connection[tableLists.size()];
        callableStatement = new CallableStatement[tableLists.size()];
        methods = new ArrayList[tableLists.size()];

        for (Map<String, String> map : tableLists.values()) {

            dbConnection[j] = getDBConnection(map.get("URL"), map.get("USER"), map.get("PASSWORD"), map.get("DRIVER"));
            callableStatement[j] = dbConnection[j].prepareCall(map.get("SQL"));

            methods[j] = getRequiredMethods(map.get("SUFFIX"));
            j++;
        }

        for (int userId = id; userId < id + noOfTasks; userId++) {

            for (int spot = 0; spot < dbConnection.length; spot++) {
                callableStatement[spot].setString(1, String.valueOf(userId));

                for (int i = 0; i < methods.length; i++) {
                    methods[spot].get(i).invoke(null, callableStatement[spot], userId);
                }

                long start = System.nanoTime();

                callableStatement[spot].executeUpdate(); // flush the records.

                long end = System.nanoTime() - start;

                final AtomicLong before = histogram.putIfAbsent(end / 1000000, new AtomicLong(1L));
                if (before != null) {
                    before.incrementAndGet();
                }
            }
        }
    }  finally {
        closeConnection(callableStatement, dbConnection);
    }
}
}

0 个答案:

没有答案