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