使用依赖线程工作者在Java中安排定期作业?
-
05-07-2019 - |
题
以下是我的要求的简化版
我有一个java类说包含一个方法的处理器说bigProcess()它所做的就是连接到一个文件服务器,一旦完成就下载一个指定的文件将文件保存在DB中并在那之后更新一些数据库字段在不同的表格中。
对于每个子任务,如下载文件,保存在数据库中,更新t1等字段,它使用不同的方法。
处理器类每2小时调用一次,并且必须处理每次调用大约30到40个请求。为了提高性能,我计划为每个请求跨越一个新线程(这里有30到40个线程),每个线程调用bigProcess方法。
现在我的问题是我是否需要同步bigProcess()方法中的任何代码块(这里我担心更新字段方法。有些更新方法会像selecte f1,f2,f3那样锁定一行t1用于更新,设置字段f1,f2和f3的值并发出提交)
注意:bigProcess()方法不使用类Processor的任何实例变量。
解决方案
使BigProcess成为 可赎回代码>
。当您将其提交到 执行者
或 ExecutorService
你得到一个 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,依此类推。
我喜欢这种方法,因为一切都是短暂的。对于来自数据库的单个负载,将创建,运行和丢弃所有进程。当你开始创建持久性线程池时,你会引入另一个潜在的问题,并且很难弄清楚发生了什么。
其他提示
是否需要同步方法取决于这些方法实际执行的操作。通常,如果存在从多个线程使用的资源(例如,数据库中的单个文件或单个表(您实际写入和读取),则需要进行同步)。如果您运行的所有进程都没有相互干扰,则不需要同步。