用Java开发多线程应用程序

时间:2012-03-06 16:21:34

标签: java multithreading

这将是我的第一个多线程应用程序,如果它可以这样开发。所以我需要一些帮助才能开始。

我目前有以下JAVA程序运行良好

  1. 从源数据库获取数据并将其转换为对象(PO​​JO)
  2. 从目标数据库获取数据并将其转换为对象(PO​​JO)。
  3. 比较源和目标对象,如果存在差异,则使用源数据库中的信息更新目标数据库。
  4. 现在我的要求已经改变,我需要使用3个不同的目标数据库(TargetDB1,TargetDB2,TargetDB3)。每个人都有不同的连接信息。

    我的问题是,我们可以将其作为

    中的多线程应用程序

    线程1将获得源对象

    线程2将获取TargetDB1对象,与源对象(从线程1获得)进行比较,并在与源对象不同的情况下更新TargetDB1

    线程3将获取TargetDB2对象,与源对象(从线程1获得)进行比较,并在与源对象不同的情况下更新TargetDB2

    线程4将获取TargetDB2对象,与源对象(从线程1获得)进行比较,并在与源对象不同的情况下更新TargetDB2

    如果可以将其开发为多线程应用程序,那么该怎么做呢。

1 个答案:

答案 0 :(得分:1)

我会使用BlockingQueue之类的LinkedBlockingQueue为每个目标数据库创建一个工作队列。生产者线程将从源数据库获取对象,然后将其添加到每个工作队列中。然后,连接到目标数据库的每个线程都可以从其工作队列中出列,并以自己的速度更新其数据库。

源数据库线程可能类似于:

// 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);
            }
        }
    }
}

此模型的一个问题是目标数据库线程是否需要以任何方式更新源对象。如果是这种情况,则必须同步对象。

请注意,可以使用容量设置阻止队列。如果生成器从源数据库读取比读取目标数据库编写者更新数据库更容易,这将非常有用。您不希望队列填满内存,因为目标数据库很慢。