0

私は、異なるスキーマを持つ異なるデータベースに2つのテーブルがあるプロジェクトに取り組んでいます。つまり、JDBCを使用して接続する2つのテーブルに2つの異なる接続パラメーターがあることを意味します-

以下がconfig.propertyファイルであると仮定しましょう。

TABLES: table1 table2

#For Table1
table1.url: jdbc:mysql://localhost:3306/garden
table1.user: gardener
table1.password: shavel
table1.driver: jdbc-driver
table1.percentage: 80
table1.columns: COL1,COL2,COl3,Col4,COL5

#For Table2
table2.url: jdbc:mysql://otherhost:3306/forest
table2.user: forester
table2.password: axe
table2.driver: jdbc-driver
table2.percentage: 20
table1.columns: COL10,COL11,COl12,Col13,COL14

config.properties以下のメソッドは、上記のファイルを読み取り、TableConnectionInfo各テーブルのオブジェクトを作成します。

private static void readPropertyFile() throws IOException {

    prop.load(LnPRead.class.getClassLoader().getResourceAsStream("config.properties"));

    tableNames = Arrays.asList(prop.getProperty("TABLES").trim().split(","));

    for (String arg : tableNames) {

        TableConnectionInfo ci = new TableConnectionInfo();
        ArrayList<String> columns = new ArrayList<String>();

        String table = prop.getProperty(arg + ".table").trim();
        columns = new ArrayList<String>(Arrays.asList(prop.getProperty(arg + ".columns").split(",")));

        ci.setTableName(table);
        ci.setColumns(columns);

        tableList.put(arg, ci);
    }
}   

以下は、特定のテーブルのTableConnectionInfo classすべてを保持するものです。table connection info

public class TableConnectionInfo {

    public String tableName;
    public ArrayList<String> columns;


    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public ArrayList<String> getColumns() {
        return columns;
    }

    public void setColumns(ArrayList<String> columns) {
        this.columns = columns;
    }
}

今、私はExecutorService指定された数のスレッドを作成し、このtableListオブジェクト(を読んで作成したものconfig.property file)をのコンストラクターに渡します。Task classその後、このtableListオブジェクトはどのスレッドによっても変更されず、各スレッドのみが値にアクセスします-

// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(10);

long startTime = System.currentTimeMillis();
long endTime = startTime + (durationOfRun * 60 * 1000);

for (int i = 0; i < threads; i++) {
    service.submit(new Task(endTime, tableList));
}

以下は、Runnableインターフェイスを実装する私のタスククラスです

class Task implements Runnable {

    private static Random random = new SecureRandom();
    private final long endTime;
    private final LinkedHashMap<String, TableConnectionInfo> tableLists;

    public Task(long endTime, LinkedHashMap<String, TableConnectionInfo> tableList) {
        this.endTime = endTime;
        this.tableLists = tableList;
    }

    @Override
    public void run() {

        while (System.currentTimeMillis() <= endTime) {

            .....

            double randomNumber = random.nextDouble() * 100.0;
            TableConnectionInfo table = selectRandomTable(randomNumber);

            /* Below line is Thread Safe right? 
             * And there won't be any issue with it? As I am doing
             * table.getColumns which will returns me an ArrayList of columns
             */
            final String columnsList = getTableColumns(table.getColumns());

            ....
        }
      }

     private String getTableColumns(final List<String> columns) {

      ...

     }
}

問題文:-

上記のrunメソッドでは、をgetColumns使用して特定のテーブルのメソッドにアクセスしようとしtable.getColumnsていますが、各スレッドは同じことを実行します。それがスレッドセーフかどうかはわかりません。また、競合状態やその他の問題などの問題は発生しません。どんな考えでも大いに役立ちます。

4

1 に答える 1

0

これは、基礎となるArrayListが最初の構築後に変更されない限り、技術的にスレッドセーフです。この場合の各スレッドは、ArrayListの同じインスタンスを参照します。

将来、これらのテーブル列を変更可能にする計画がある場合、問題が発生する可能性があります。このリストが可変である場合は、新しいリストとポインタースワップを作成するか、java.util.concurrent。*クラスを使用して列のリストを保持します。

于 2013-03-04T00:44:04.187 に答える