3

私は並行プログラミングに不慣れで、処理される項目のキューを持つコードに取り組んでいます。これは、ユーザーが指定した数のワーカースレッドに渡されます。現時点では、2つのワーカースレッドとメインでそれを実行しようとしました。

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クラスです。2つの新しいスレッドを作成するだけで、このクラスを呼び出そうとしました。

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

これが正しいかどうかわかりませんか、それとも参加を待っているために何かメリットがありますか?助けてくれてありがとう。

4

3 に答える 3

2

これを行うためのはるかにクリーンでスケーラブルな方法は、Executorsクラスによって作成されたスレッドプールを使用することです。

ちなみに、このVectorクラスは廃止されており、もう使用しないでくださいArrayList。代わりに使用して、使用方法を学んだ本やチュートリアルをダンプしてくださいVector。10年以上前のものです。

于 2011-11-24T23:49:34.480 に答える
1

ほんの少しの参考文献ですが、anとaまたは。とBlockingQueue一緒に使用したいと思います。ExecutorServiceRunnableCallable

final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());おそらくインスタンス変数ですら(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のEffectiveJavaをお勧めします。

于 2011-11-24T23:55:36.907 に答える
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ミリ秒待機したかったのですが、これはオプションです。これがお役に立てば幸いです。

于 2011-11-25T00:08:35.380 に答える