2012-03-06 5 views
0

これは私の最初のマルチスレッドアプリケーションであれば開発できます。だから私は始めるためにいくつかの助けが必要です。Javaでマルチスレッドアプリケーションを開発する

私は現在、完璧に

の作品次のJavaプログラム
  1. を持って
  2. (POJOの)ソース・データベースからデータを取得し、オブジェクトに変換(ターゲット・データベースからデータを取得し、オブジェクトに変換POJO)。
  3. ソースオブジェクトとターゲットオブジェクトの両方を比較し、差異がある場合は、ソースデータベースの情報でターゲットデータベースを更新します。

私の要件が変更され、3つの異なるターゲットデータベース(TargetDB1、TargetDB2、TargetDB3)を使用する必要があります。それぞれに異なる接続情報があります。

私の質問は、私たちはこの

スレッド1で(スレッド1から得られた)ソースオブジェクトと比較し、TargetDB1オブジェクトを取得するソースオブジェクト

スレッド2を取得するマルチスレッドのアプリケーションにすることができていますソースオブジェクトとの相違の場合に

(スレッド1から得られた)ソースオブジェクトと比較し、TargetDB2オブジェクトを取得する糸3をTargetDB1を更新し、ソースオブジェクトとの相違の場合にTargetDB2を更新

スレッド4はTargetDB2オブジェクトを取得し、ソースオブジェクト(スレッド1から取得)と比較し、ソースオブジェクトとの違いがある場合はTargetDB2を更新します

これはマルチスレッドアプリケーションとして開発できる場合、それについて。

+3

本当にアプリケーションレイヤーでこれを行いますか?大量の場合は、データベースユーティリティを使用する方が速くなります。単純にいくつかのSQL文と.csvを使用するだけで、おそらくもっと速くなります。 –

+0

これがdbsを同期させる最良の方法かどうかはわかりません。DB1がマスタDBの場合、私の意見では他のDBのアップグレードスクリプトを書く方が良いでしょう。 – FourOfAKind

+0

私は複数のスレッドを使用しませんが、私は一貫性を心配しています。例えばDB1,2,3が異なっていると言います。一度に2つだけを比較する場合、3つのデータベースがすべて同じ値になるようにする必要があります。 –

答えて

1

のようなBlockingQueueを使用して、ターゲットデータベースごとにワークキューを作成します。プロデューサスレッドはオブジェクトをソースデータベースから取得し、それを各作業キューに追加します。次に、ターゲット・データベースに接続されている各スレッドは、その作業キューからデキューして、独自の速度でデータベースを更新できます。

ソース・データベースのスレッドは次のようになります。

// allow only 10 outstanding objects to be in the work queue before it blocks 
queue1 = new LinkedBlockingQueue<SourceObject>(10); 
new Thread(new TargetDatabaseThread("url-to-database1", queue1)).start(); 
queue2 = new LinkedBlockingQueue<SourceObject>(10); 
new Thread(new TargetDatabaseThread("url-to-database2", queue2)).start(); 
queue3 = new LinkedBlockingQueue<SourceObject>(10); 
new Thread(new TargetDatabaseThread("url-to-database3", queue3)).start(); 
while (true) { 
    SourceObject sourceObj = getFromSourceDatabase(); 
    // this might block if you set a capacity on your queue and it was full 
    queue1.put(sourceObj); 
    queue2.put(sourceObj); 
    queue3.put(sourceObj); 
} 

ターゲット・データベース・スレッドの各その後、次のようになります。ターゲット・データベース・スレッドが必要な場合は、このモデルで

public class TargetDatabaseThread implements Runnable { 
    private final String jdbcUrl; 
    private final BlockingQueue queue; 
    private volatile boolean shutdown; 
    public TargetDatabaseThread(String jdbcUrl, BlockingQueue queue) { 
     this.jdbcUrl = jdbcUrl; 
     this.queue = queue; 
    } 
    public void run() { 
     // maybe some initialization, make database connection, etc. 
     while (!shutdown) { 
      // this would block if nothing is in the queue 
      SourceObject sourceObj = queue.take(); 
      SourceObject targetObj = 
       getObjectFromTargetDatabase(sourceObj.getId()); 
      if (updateTarget(sourceObj, targetObj)) { 
       updateMyTargetObjectInDatabase(targetObj); 
      } 
     } 
    } 
} 

一つの問題は次のようになります任意の方法でソースオブジェクトを更新します。この場合、オブジェクトを同期させる必要があります。

ブロッキングキューは容量で設定できます。これは、プロデューサがソースデータベースから読み取る方が、ターゲットデータベース作成者がデータベースを更新するよりも簡単な場合に役立ちます。ターゲットデータベースが遅いため、キューにメモリがいっぱいになることは望ましくありません。

+0

@Gary..thanksあなたの返信です。私はソースデータベースを更新する必要はありません。コードスニペットありがとう。これが初めてのので、コードを精緻化することはできますか?現在は、フェッチ全体の処理、比較前のConflictCheck、更新前のConflictCheck、更新(削除と挿入の両方)操作を処理するための多くのメソッドを備えた巨大なクラスがあります。異なるスレッドが同じプログラムを使用するように、どうすればそれらを使用できますか?基本的には、これらのスレッドクラスはどのように見えるのですか?mainメソッドでどのように実行されますか? – Raghu

+0

スレッドはすべて、同じ 'ConflictCheck'メソッドなどを持つ同じクラスになります。おそらくそれを 'TargetDatabaseThread'とかそのようなものと呼んでください。そのコンストラクタへの引数の1つは、 'take()'を呼び出す 'BlockingQueue'でしょう。 – Gray

+0

少し私の答えを編集しました@Raghu。運が良かった。 – Gray