2011-11-24 55 views
3

我不熟悉并发编程,并且一直在处理具有要处理的项目队列的代码,这会传递给某些工作线程,即由用户指定的编号。目前,我只是试图用两个工作线程加上主线程来完成它。在Java中使用多个线程

private static class workerThread extends Thread { 

     workerThread(){ 
      super(); 
     } 


     public void run(){ 
      while (!workQueue.isEmpty()) { 

      String x = workQueue.remove(); 
      //System.out.println("work queue size: " + workQueue.size()); 
      Vector<String> list2 = new Vector<String>((Vector) table.get(x)); 
      list2 = process(x, list2); 
      //System.out.println(list2 + "list2"); 
      table.put(x, list2); 

      //System.out.println(x + "key" + "value" + vvv); 

     } 

     } 

这就是线程的WorkerThread类,我已经尝试了通过创建两个新线程调用它:

workerThread wt = new workerThread(); 
    workerThread wt2 = new workerThread(); 
    wt.start(); 
    wt2.start(); 
    try { 
     wt.join(); 
     wt2.join(); 
    } catch (InterruptedException ex) { 
     Logger.getLogger(includeCrawler.class.getName()).log(Level.SEVERE, null, ex); 
    } 

我不知道这是否正确,或将因任何benfit等待连接?谢谢你的帮助。

回答

2

一个更清洁和可扩展的方法是使用由Executors类创建的线程池。

顺便说一句,在Vector类是过时的,不应该再使用 - 使用ArrayList来代替,而在这里你学会了用Vector转储任何书籍或教程 - 这是十年以上过时。

+0

我觉得Sarconi会从首先理解线程中受益 – MadcoreTom

+0

我有一点看线程池,但这个练习似乎有点复杂。哦,我用了一个Vector,因为它是同步的。我没有意识到它已经过时了。 – drunkmonkey

+0

来自C++开发,我可以肯定地说,不要使用'Vector',只是为了心理一致性。并不是说它更好,只是这可能是海报使用它的原因。 – jli

1

只是几个参考,我想你想要使用BlockingQueue以及ExecutorServiceRunnableCallable。也许甚至是一个实例变量(private static final ExecutorService POOL = ...)。对于I/O绑定应用程序,您可能想要使用比可用处理器更多的线程。然后再次您不想使用Vector。使用另一个List实现(通常使用ArrayList)。

顺便说一句:如果你想掌握并发编程,你可能也想阅读Akka和Actors/STM,而不是使用通常的共享可变性模型。

编辑:我肯定会推荐http://pragprog.com/book/vspcon/programming-concurrency-on-the-jvm和Josh(ua)Bloch的Effective Java。

1

您一定要使用执行程序。这是一个仅供参考的例子。它适用于单个线程,但我认为这对您而言是一个好的开始。它很容易适应任意数量的线程。

ExecutorService executor = Executors.newSingleThreadExecutor(); 
Future<MyObject> f = 
    executor.submit(new Callable<MyObject>() { 

     @Override 
     public MyObject call() throws Exception { 
     MyObject obj = new MyObject(); 
     // do stuff 
     return obj; 
     } 

    }); 

MyObject myObject = 
    new MyObject(); 

try { 
    myObject = f.get(500, TimeUnit.MILLISECONDS); 
} 
catch (InterruptedException e) { 
    // stuff 
} 
catch (ExecutionException e) { 
    // stuff 
} 
catch (TimeoutException e) { 
    // stuff 
} 
finally { 
    executor.shutdown(); 
} 

在这种情况下,我想在超时前最多等待500毫秒,但这是可选的。 希望这可以帮助。

+0

java Future.get ==阻塞==杀死可扩展性 –

+0

@ViktorKlang:你有更多的信息吗?我想更深入地讨论这个话题。你能分享一些链接吗? 10x – loscuropresagio

+0

阻塞==暂停线程==少线程活动==可以完成较少的工作==较少的可伸缩性==较低的性能 –