首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从Java线程返回值

从Java线程返回值
EN

Stack Overflow用户
提问于 2010-02-23 05:37:26
回答 8查看 31.8K关注 0票数 20

我有一个Java线程,如下所示:

代码语言:javascript
复制
   public class MyThread extends Thread {
        MyService service;
        String id;
        public MyThread(String id) {
            this.id = node;
        }
        public void run() {
            User user = service.getUser(id)
        }
    }

我有大约300个id,每隔几秒钟-我会启动线程来调用每个id。例如:

代码语言:javascript
复制
for(String id: ids) {
    MyThread thread = new MyThread(id);
    thread.start();
}

现在,我想收集每个线程的结果,并对数据库执行一次批量插入,而不是每2秒执行300次数据库插入。

你知道我该怎么做吗?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-02-23 06:00:18

如果希望在进行数据库更新之前收集所有结果,可以使用invokeAll方法。这就像daveb建议的那样,如果你一次提交一个任务,就需要记账。

代码语言:javascript
复制
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. */
...
票数 22
EN

Stack Overflow用户

发布于 2010-02-23 05:39:27

规范的方法是使用CallableExecutorService。将Callable设置为ExecutorService会返回一个(类型安全的) Future,您可以从中get结果。

代码语言:javascript
复制
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

在您的示例中,您可能希望使用返回Futures ListinvokeAll,或者在向executor添加任务时自己创建该列表。要收集结果,只需对每个结果调用get

票数 35
EN

Stack Overflow用户

发布于 2010-02-23 06:07:58

将结果存储在对象中。当它完成时,让它把自己放到一个同步的集合中(想到的是一个同步队列)。

当您希望收集要提交的结果时,从队列中抓取所有内容,并从对象中读取结果。您甚至可以让每个对象知道如何将它自己的结果"post“到数据库中,这样就可以提交不同的类,并使用完全相同的小而优雅的循环来处理所有类。

JDK中有很多工具可以帮助你做到这一点,但是一旦你开始把你的线程看作一个真正的对象,而不只是一堆关于"run“方法的废话,事情就变得很简单了。一旦你开始以这种方式思考对象,编程就会变得更加简单和令人满意。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2314402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档