Lan*_*ali 18 java concurrency multithreading
我有一个类似以下的Java线程:
public class MyThread extends Thread {
MyService service;
String id;
public MyThread(String id) {
this.id = node;
}
public void run() {
User user = service.getUser(id)
}
}
Run Code Online (Sandbox Code Playgroud)
我有大约300个ID,每隔几秒钟 - 我启动线程来为每个id打个电话.例如.
for(String id: ids) {
MyThread thread = new MyThread(id);
thread.start();
}
Run Code Online (Sandbox Code Playgroud)
现在,我想从每个线程收集结果,并对数据库进行批量插入,而不是每2秒进行300次数据库插入.
知道我怎么能做到这一点?
dav*_*veb 35
规范的方法是使用a Callable和a ExecutorService. submita Callable到a ExecutorService返回一个(类型安全)Future,你可以从中get得到结果.
class TaskAsCallable implements Callable<Result> {
@Override
public Result call() {
return a new Result() // this is where the work is done.
}
}
ExecutorService executor = Executors.newFixedThreadPool(300);
Future<Result> task = executor.submit(new TaskAsCallable());
Result result = task.get(); // this blocks until result is ready
Run Code Online (Sandbox Code Playgroud)
在你的情况,你可能想使用invokeAll它返回List的Futures为你添加任务执行人,或创建一个列表你自己.要收集结果,只需打电话get给每一个.
eri*_*son 19
如果要在执行数据库更新之前收集所有结果,可以使用该invokeAll方法.如果您一次提交一项任务,这就照顾了所需的簿记,如daveb建议的那样.
private static final ExecutorService workers = Executors.newCachedThreadPool();
...
Collection<Callable<User>> tasks = new ArrayList<Callable<User>>();
for (final String id : ids) {
tasks.add(new Callable<User>()
{
public User call()
throws Exception
{
return svc.getUser(id);
}
});
}
/* invokeAll blocks until all service requests complete,
* or a max of 10 seconds. */
List<Future<User>> results = workers.invokeAll(tasks, 10, TimeUnit.SECONDS);
for (Future<User> f : results) {
User user = f.get();
/* Add user to batch update. */
...
}
/* Commit batch. */
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28915 次 |
| 最近记录: |