使用依赖线程工作者在Java中安排定期作业?

时间:2009-09-10 09:40:23

标签: java multithreading synchronization

以下是我的要求的简化版

我有一个java类说包含一个方法的处理器说bigProcess()它所做的只是连接到一个文件服务器,一旦完成就下载一个指定的文件保存在DB中的文件,之后更新一些数据库字段在不同的表格中。

对于每个子任务,如下载文件,保存在数据库中,更新t1等字段,它使用不同的方法。

处理器类每2小时调用一次,并且必须处理每次调用大约30到40个请求。为了提高性能,我计划为每个请求跨越一个新线程(这里有30到40个线程),每个线程调用bigProcess方法。

现在我的问题是我是否需要同步bigProcess()方法中的任何代码块(这里我担心更新字段方法。有些更新方法会像selecte f1,f2,f3那样锁定一行t1用于更新,设置字段f1,f2和f3的值并发出提交)

注意:bigProcess()方法不使用类Processor的任何实例变量。

2 个答案:

答案 0 :(得分:3)

让BigProcess成为Callable。当您将其提交到ExecutorExecutorService时,您会收到Future。如果在30-40个线程中执行future.get(),则这些线程将阻塞,直到Callable完成。或者,如果Callable已完成,他们将立即返回结果。

另一种方法(我非常喜欢)是创建一个线程池,将所有工作提交给线程池。提交完所有工作后,关闭并等待终止。它看起来像这样:

ExecutorService threadPool = Executors.newFixedThreadPool(40);
// submit work
threadPool.shutdown();
try {
  threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
  // do something
}

如果你有依赖工作(比如在任务A完成之前无法完成任务B),那么从任务A创建一个带有Future的任务B,依此类推。

我喜欢这种方法,因为一切都是短暂的。对于来自数据库的单个负载,将创建,运行和丢弃所有进程。当你开始创建持久性线程池时,你会引入另一个潜在的问题,并且很难弄清楚正在发生的事情。

答案 1 :(得分:1)

是否需要同步方法取决于这些方法实际执行的操作。通常,如果存在从多个线程使用的资源(例如,数据库中的单个文件或单个表(您实际写入和读取),则需要进行同步)。如果您运行的所有进程彼此不相互干扰,则无需同步。