16

Collection インスタンスの要素を同時に処理する必要があります。つまり、 Collection インスタンスを反復する代わりに

for (Someclass elem : coll){
     process(elem);
}

これらの要素を同時に処理したいと思います。のようなものを言ってConcurrentCollectionExecutor(coll, new Callable{…}, numberOfThreads)ください。また、同時スレッド数を修正する必要があります。

柔軟なパターンは既に存在しますか?

4

4 に答える 4

8

良い解決策は次のとおりです。

  1. 処理する要素を含むArrayBlockingQueueをインスタンス化します
  2. ExecutorServiceをインスタンス化して、処理を同時に実行します
  3. をインスタンス化Runnableして、パラメータとしてArrayBlockingQueueを指定します
  4. メソッドを実装しrunます。キューに要素がある間に、それらをポーリングして処理します
  5. に送信RunnableしますExecutorService

コード:

BlockingQueue<Someclass> toProcess = 
    new ArrayBlockingQueue<Someclass>(coll.size(), false, coll);
ExecutorService es = Executors.newFixedThreadPool(numberOfThreads);
for(int count = 0 ; count < numberOfThreads ; ++c) {
    es.submit(new MyRunnable(toProcess));
}


private static class MyRunnable() implements Runnable {
    private final BlockingQueue<Someclass> toProcess;

    public MyRunnable(BlockingQueue<Someclass> toProcess) {
        this.toProcess = toProcess;
    }

    @Override
    public void run() {
        Someclass element = null;
        while((element = toProcess.poll()) != null) {
            process(element);
        }
    }
}
于 2013-02-08T08:38:13.823 に答える
8

プロセス メソッドを、Runnable を実装する MyRunnable というクラスの run() メソッドにし、コンストラクターが入力として elem を受け取り、それをインスタンス変数として格納します。次に使用します。

ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
for (Someclass elem : coll){
   Runnable worker = new MyRunnable(elem);
   executor.execute(worker);
}
于 2013-02-08T08:32:35.580 に答える
2

そのようなエグゼキュータクラスの「手作り」バージョンの下。Callable(またはRunnable) のインスタンスではなく、そのようなプロセッサ クラスのクラス名を渡す必要があることに注意してください。

public class ConcurrentCollectionExecutor<T> {

private Collection<T> collection;
private Class<Runnable> processor;
private int numberOfThreads;
private Executor executor;

public ConcurrentCollectionExecutor(Collection<T> collection, Class<Runnable> processor, int numberOfThreads) {
    this.collection = collection;
    this.processor = processor;
    this.numberOfThreads = numberOfThreads;
    this.executor = Executors.newFixedThreadPool(numberOfThreads);
}

public void run() {
    try {
        Constructor<Runnable> constructor = null;
        for (T t : collection) {
            if (constructor == null) {
                constructor = processor.getConstructor(t.getClass());
            }
            executor.execute(constructor.newInstance(t));
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}      
}
于 2013-02-08T08:43:16.600 に答える
0

これに関するパターンはわかりませんが、アイデアとして、コレクション要素をスレッド数で分割できるため、各スレッドは処理する X 要素を取得します。次に例を示します。

コレクションには 20 の要素があり、すべての機能で 4 つのスレッドを提供し、次のようにインターンを開始します。

thread1 gets the elements [0 .. 4]
thread2 gets the elements [5 .. 9]
thread3 gets the elements [10 .. 14]
thread1 gets the elements [15 .. 19]

コレクションから要素を削除すると問題が発生する可能性があることに注意してください。特に、コレクション内の要素が 20 未満のときに、スレッド 4 が要素 [19] にアクセスしようとします。

編集

要素の処理時間に応じて脳が述べたように、このアイデアは、最初の 5 つの要素の 1 つを処理するのに 10 秒かかったが、他の要素の処理に 0.5 秒しかかからなかった場合、スレッド 1 はビジーになりますが、他のスレッドはそうではありません。非常に長い間並行して実行されています。

于 2013-02-08T08:33:57.320 に答える