如何从早期得到结果的两个线程的结果中发布结果?

时间:2014-03-27 12:33:02

标签: java multithreading

我有两个课程:TNsyncer.javaDNSClient.java。 两者都给出相同的结果,但用于获得结果的方法是不同的

现在我有一个班级Main.java

我希望通过在Main.java的两个不同线程中调用该类来填充结果,并在此基础上发布结果:

  • 如果任何线程首先得到结果,这将给我结果,如果一个失败(Exception),那么等待第二个
  • 如果两者都失败,则发布最终的异常状态

这两个类都会抛出异常。

我正在做这样的事情:

Object o =new Object();

Thread searchThread = new Thread(new Runnable() {
     @Override
     public void run() {
          info = new DNSClient(getApplicationContext()).checkDNSAnswer(nameSearch.getText().toString());
          catch (final Exception ex) { Post some result;}

     Thread searchThread2 =new Thread(new Runnable() {  
         @Override
         public void run() {
             new TnSyncer().getInstance().sync(nameSearch.getText().toString(),CallerId.getInstance().getPreferences().getCountryCode()) ;
             catch (final Exception ex) { Post some result;}

           Thread third = new Thread(new Runnable() {
               @Override
               public void run() {
                   synchronized(o1){
                       try {
                           wait();
                       } catch (InterruptedException e) {
                           e.printStackTrace();
                       }
                   }
               }
           });

我已经放了我的代码,需要等待一个对象,但问题是如果我等待同一个对象,那么两个线程都不会同时运行

3 个答案:

答案 0 :(得分:1)

您可以将TNSyncerDNSClient建模为java.util.concurrent.Callable接口的实现。可以将Callables提交给Executor,您可以使用java.util.concurrent.Future等待其结果。

如果您想等待任何结果,可以使用java.util.concurrent.CompletionService

的实现

示例:

class Result {
}

class TnSyncer implements Callable<Result> {
    @Override
    public Result call() throws Exception {
        // TODO: implement
    }
}

class DnsClient implements Callable<Result> {
    // [...]
}

static Executor executor = new ScheduledThreadPoolExecutor(6);

public static Result lookup(String host) {
    ExecutorCompletionService<Result> service = new ExecutorCompletionService<>(executor);
    service.submit(new TnSyncer(host));
    service.submit(new DnsClient(host));
    return service.take().get();
}

Executor有多个实现,您应该查看它们,确定您希望线程池的大小等等。

答案 1 :(得分:0)

如果你想找到哪一个更快。只需将它们计时并以更好的时间打印方法会更容易。否则,您可能希望查看类似协程的内容,或者更好地管理线程的某种方式。我认为第一种方式适合你想做的更好。

答案 2 :(得分:0)

您可以尝试使用任务和响应队列与在不同线程中运行的“服务”进行通信的方法。以下策略显示了这种方法:

  • 制作TNSyncher和DNSClient,每个实现接口Runnable;使用输入和输出队列创建和启动每个。
  • 在每个客户端检查“任务”队列,等待(暂时休息),如果没有
  • 在您的主要文件中将您请求的任务添加到每个队列
  • 在您的主要问题中等待并检查每个响应队列;如果异常等待第二次胜利或例外,则处理您的第一个获胜者。

(在你的每个单独的线程任务中,你可以通过检查中止信号或停止和退出信号来改善事情..如果你得到胜利者则使用前者,而当你想要阻止那些时候使用后者线程)