在Java中使用多个线程

在Java中使用多个线程,java,multithreading,concurrency,task-queue,worker,Java,Multithreading,Concurrency,Task Queue,Worker,我是并发编程的新手,一直在编写代码,其中有一个要处理的项目队列,该队列被传递给一些工作线程,数量由用户指定。目前,我只是尝试使用两个辅助线程加上主线程 private static class workerThread extends Thread { workerThread(){ super(); } public void run(){ while (!workQueue.isEmpty

我是并发编程的新手,一直在编写代码,其中有一个要处理的项目队列,该队列被传递给一些工作线程,数量由用户指定。目前,我只是尝试使用两个辅助线程加上主线程

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);

        }

        }

我不确定这是否正确,或者是否会因为等待加入而有任何好处?感谢您的帮助。

一种更简洁、更具可扩展性的方法是使用类创建的线程池


顺便说一句,
Vector
类已经过时,不应该再使用了-改用
ArrayList
,把你学会使用
Vector的任何书籍或教程都扔掉-它已经过时十多年了。

只是一些参考资料,我想您应该使用
阻塞队列
以及
执行服务
可运行
可调用

final ExecutorService executor=Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())甚至可能是一个实例变量(私有静态最终执行器服务池=…)。对于I/O绑定的应用程序,您可能希望使用比可用处理器更多的线程。然后,您又不想使用
向量
。使用另一个
列表
实现(通常要使用的是
ArrayList

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


编辑:我肯定会推荐Josh(ua)Bloch提供的高效Java。

您一定要使用Executors。这是一个仅供参考的例子。它只在一个线程上工作,但我认为这对您来说是一个好的开始。它很容易适应任意数量的线程

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();
}
ExecutorService executor=Executors.newSingleThreadExecutor();
未来f=
执行人提交(新的可调用(){
@凌驾
公共MyObject调用()引发异常{
MyObject obj=新的MyObject();
//做事
返回obj;
}
});
肌体肌体=
新的MyObject();
试一试{
myObject=f.get(500,时间单位为毫秒);
}
捕捉(中断异常e){
//东西
}
捕获(执行例外){
//东西
}
捕获(超时异常e){
//东西
}
最后{
executor.shutdown();
}
在本例中,我希望在超时之前最多等待500毫秒,但这是可选的。
希望这能有所帮助。

我想Sarconi会从理解线程中获益。我看了一下线程池,但这个练习似乎有点复杂。哦,我用了一个向量,因为它是同步的。我没有意识到它已经过时了。从C++开发中,我可以肯定的说,仅仅为了精神一致,很难不使用<代码>向量<代码>。并不是说它更好,只是这可能是海报使用它的原因。@Sarconi:它肯定不会比手动管理可变数量的线程更复杂。当每个实例一次只被一个线程使用时,向量的同步似乎不相关。java Future.get==blocking==killsscalability@ViktorKlang:你有更多的信息吗?我想更深入地讨论这个话题。你能分享一些链接吗?10xblocking==暂停线程==活动线程数减少==可以完成的工作量减少==可伸缩性减少==性能降低在您的示例中,您有两个线程,调用方和ExecutorService中的线程。当您执行Future.get时,这意味着您有1个线程暂停,1个线程正在工作。如果有100个呼叫者,则有100个线程暂停,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();
}