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

#For Table2
table2.url: jdbc:mysql://otherhost:3306/forest
table2.user: forester
table2.password: axe
table2.driver: jdbc-driver

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

  private static void readPropertyFile() throws IOException {

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

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

    for (String arg : tableNames) {

        ReadTableConnectionInfo ci = new ReadTableConnectionInfo();

        String url = prop.getProperty(arg + ".url");
        String user = prop.getProperty(arg + ".user");
        String password = prop.getProperty(arg + ".password");
        String driver = prop.getProperty(arg + ".driver");

        ci.setUrl(url);
        ci.setUser(user);
        ci.setPassword(password);
        ci.setDriver(driver);

        tableList.put(arg, ci);

    }
}

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

public class ReadTableConnectionInfo {

    public String url;
    public String user;
    public String password;
    public String driver;
    public String percentage;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }
}

今、私はExecutorService指定された数のスレッドを作成し、このtableListオブジェクト(を読んで作成したもの)を-config.property fileのコンストラクターに渡します。ReadTask class

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

for (int i = 0; i < 10; i++) {
    service.submit(new ReadTask(tableList));
}

以下は、意味のあることを行う前に、各スレッドが最初にテーブルごとに2つの接続を確立するようにReadTask実装する私のクラスです。Runnable interface

class ReadTask implements Runnable {

    private Connection[] dbConnection = null;
    private ConcurrentHashMap<ReadTableConnectionInfo, Connection> tableStatement = new ConcurrentHashMap<ReadTableConnectionInfo, Connection>();

    public ReadTask(LinkedHashMap<String, XMPReadTableConnectionInfo> tableList) {
        this.tableLists = tableList;
    }


    @Override
    public void run() {

        try {

            int j = 0;
            dbConnection = new Connection[tableList.size()];

            //loop around the map values and make the connection list
            for (ReadTableConnectionInfo ci : tableList.values()) {

                dbConnection[j] = getDBConnection(ci.getUrl(), ci.getUser(), ci.getPassword(), ci.getDriver());
                tableStatement.putIfAbsent(ci, dbConnection[j]);

                j++;
            }

            //do other meaningful thing here
           }
       }
    }

上記のtryブロックでは、dbConnection array2つの異なるデータベース接続を格納するために作成しています。そして、オブジェクトをtableStatement格納しているasConcurrentHashMapがあります。たとえば、Table1オブジェクトはConcurrentHashMapにTable1接続を持ちます。ReadTableConnectionInfodbConnectiontableStatement

問題文:-

ConcurrentHashMapに挿入する方法や、その他のスレッドセーフの問題thread safety issuesを使用して、runメソッドに潜在的な可能性があるかどうかを確認しようとしていますか?tableStatement

4

1 に答える 1

0

あなたはタスククラスがスレッド間で共有されていないため(現在の例では)、オブジェクトの内部状態にアクセスする際の同時実行の問題はありません。現在、タスクの各インスタンスは、エグゼキュータによって割り当てられたスレッドでのみアクセスされます。

service.submit(new ReadTask(tableList));

上記のコード行を使用して、のインスタンスをインスタンス化しReadTask、エグゼキュータに別のスレッドで実行するように依頼します。他のスレッドでオブジェクトにアクセスしない場合は、同時実行の問題はありません。

あなたの例では、実際には、同時ハッシュマップを使用する必要はありません(外部オブジェクトがそのコレクションを変更するための手段を提供していないため)。

コードを変更するために何かをしたい場合は、ReadTableConnectionInfoオブジェクトを不変にすることを検討してください。これは次の方法で実行できます。

  • 各クラスのインスタンス変数をfinalとして宣言します。
  • インスタンス変数のそれぞれの値を受け入れるコンストラクターを提供する
  • クラスsetterメソッドの削除
  • メソッドで新しいコンストラクターを使用するreadPropertyFile
于 2013-02-26T03:10:16.020 に答える