2013-08-22 20 views
0

我的两个类中有一个接受字符串映射的进程方法。如何调用使用多线程而不是按顺序的方法

在下面的代码中,我使用了一个for循环,它将逐个调用我的两个类中的process方法,这很好。

for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) { 
    final Map<String, String> response = entry.getPlugin().process(outputs); 

    System.out.println(response); 
} 

但是有没有什么办法可以为此启动两个线程?一个线程会调用我的一个类的进程方法,第二个线程会调用我的第二个类的进程方法?然后在得到每个线程的响应之后,我想写入数据库。这意味着每个线程将写入数据库。

而且每个线程也应该有超时功能。我们将等待每个线程一段指定的时间,这意味着如果某个进程方法没有在一定时间内返回,那么它将获得超时。

这是可能做我的使用情况?如果是的话,任何人都可以提供一个如何做到这一点的例子吗?谢谢。

任何帮助将不胜感激。

回答

2

您可以创建一个ExecutorService,并分配您想要运行的多个线程,例如,

ExecutorService executor = Executors.newFixedThreadPool(2) 

里面现在你的循环,你会做这样的事情

for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) { 
    executor.submit(new Runnable() { 
     public void run() { 
      final Map<String, String> response = entry.getPlugin().process(outputs); 
      // write to database 
      System.out.println(response); 
     } 
    } 
} 

您可能还需要有一个单独的线程处理所有数据库的写入 - 您可运行将通过发送它们的结果吧一个BlockingQueue或沿着这些线

// Three threads: one thread for the database writer, two threads for the plugin processors 
final ExecutorService executor = Executors.newFixedThreadPool(3); 

final BlockingQueue<Map<String, String>> queue = new LikedBlockingQueue<>(); 

Future future = executor.submit(new Runnable() { 
    public void run() { 
     Map<String, String> map; 
     try { 
      while(true) { 
       // blocks until a map is available in the queue, or until interrupted 
       map = queue.take(); 
       // write map to database 
      } 
     } catch (InterruptedException ex) { 
      // IF we're catching InterruptedException then this means that future.cancel(true) 
      // was called, which means that the plugin processors are finished; 
      // process the rest of the queue and then exit 
      while((map = queue.poll()) != null) { 
       // write map to database 
      } 
     } 
    } 
} 

for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) { 
    executor.submit(new Runnable() { 
     public void run() { 
      final Map<String, String> response = entry.getPlugin().process(outputs); 
      // put the response map in the queue for the database to read 
      queue.offer(response); 
     } 
    } 
} 

// this interrupts the database thread, which sends it into its catch block 
// where it processes the rest of the queue and exits 
future.cancel(true); // interrupt database thread 

// wait for the threads to finish 
executor.awaitTermination(5, TimeUnit.MINUTES); 
+0

非常感谢Zim-Zam的建议。当我在eclipse中复制完整的确切代码时。我在这行上看到了一个关于分号的编译问题:Map map;'我不知道如何解决这个问题..还可以为我的理解添加一些描述吗?它会帮助我很多..感谢您的帮助.. – AKIWEB

+0

@TrekkieTechie T-T我已经添加了一些注释并修复了编译错误。这个想法是,你创建了很多匿名的Runnables,你发送到ExecutorService,你正在初始化为三个线程(一个用于数据库编写器,两个用于插件处理器);你可以把它增加到硬件线程的数量(这是核心数量,如果你有超线程的话,是两倍)加上一个(因为数据库线程是IO绑定的)。当插件处理线程完成后,您将中断数据库处理线程,以便它最终终止。 –

+0

是的,现在makses感觉..非常感谢Zim-Zam的帮助... – AKIWEB

相关问题