1

私の質問はRunnableObject、多くの「 s」のリストのスレッド化を制御するための「最良の」方法は何ですか?

マルチスレッドにアプローチする方法はありますが、最適ではないと思います。すべて同じことを行う必要があるオブジェクトのリストがある場合がたくさんありますが、一度に1つずつ実行したくないので、それらをリストに入れて、いくつかをスレッド化します。一度。終了するとupdateList()、コントローラーのメソッドを呼び出して、完成したアイテムを削除し、新しいアイテムを呼び出します。これはあまり良い方法ではないと思います。のようなものを使用したいの.notify()ですが、このコンテキストでどのように機能するかわかりません(学習するのに適したサイトに誘導すると役立つ場合があります)。

以下に、コントローラークラスの基本的な概要を示します。私はjavadocを便利なものにしようとしたので、スキミングに興味がある場合は、先に進んでそれを読んでください。ありがとう。

私が話していることのアイデアをあなたに与えるためのほんのいくつかのサンプルコード。

package controller;

import java.util.ArrayList;
import java.util.List;
import model.RunnableObject;

public class RunnableObjectController {

  private static RunnableObjectController instance;
  private List<RunnableObject> runnableObjects = new ArrayList<>();
  private List<RunnableObject> queuedRunnableObjects = new ArrayList<>();
  private List<RunnableObject> currentRunnableObjects = new ArrayList<>();
  private int limit = 10;

  private RunnableObjectController() {
  }

  public static RunnableObjectController getInstance() {
    if (instance == null) {
      instance = new RunnableObjectController();
    }
    return instance;
  }

  /**
  * Updates the list.
  */
  public void begin() {
    updateList();
  }

  /**
   * Called by a runnableObject when it's finished with its process
   */
  public synchronized void updateList() {
    removeFinishedRunnableObjects();
    addNewRunnableObjects();
    if (isFinished()) {
      MainController.getInstance().finish();
    }
  }

  /**
  * Searches the currentRunnableObjects for runnableObjects which are not in progress and removes them from the currentRunnableObjects.
  * It will add them to the queuedRunnableObjects if they are of status WAITING.
  */
  private void removeFinishedRunnableObjects() {
    int i = 0;
    while (i < currentRunnableObjects.size()) {
      RunnableObject runnableObject = currentRunnableObjects.get(i);
      if (runnableObject.getStatus() != RunnableObject.IN_PROGRESS) {
        currentRunnableObjects.remove(runnableObject);
        if (runnableObject.getStatus() == RunnableObject.WAITING) {
          queuedRunnableObjects.add(runnableObject);
        }
      } else {
        i++;
      }
    }
  }

  /**
  * Searches the queuedRunnableObjects and adds them to the currentRunnableObjects while the size of the currentRunnableObjects is less than the limit.
  * Begins the runnableObject in a new thread and sets its status to IN_PROGRESS
  */
  private void addNewRunnableObjects() {
    while (!queuedRunnableObjects.isEmpty() && currentRunnableObjects.size() < limit) {
      RunnableObject runnableObject = queuedRunnableObjects.get(0);
      if (runnableObject.getStatus() == RunnableObject.WAITING) {
        addCurrentRemoveQueued(runnableObject);
        new Thread(runnableObject).start();
        runnableObject.setStatus(RunnableObject.IN_PROGRESS);
      }
    }
  }

  /**
  * Adds the runnableObject to the currentThreadsObjects and removes it from the queuedRunnableObjects
  */
  private synchronized void addCurrentRemoveQueued(RunnableObject runnableObject) {
    currentRunnableObjects.add(runnableObject);
    queuedRunnableObjects.remove(runnableObject);
  }

  /**
   * Checks whether the current and queued notification lists are empty. Returns true if they both are.
   *
   * @return
   */
  private boolean isFinished() {
    if (queuedRunnableObjects.isEmpty() && currentRunnableObjects.isEmpty()) {
      return true;
    }
    return false;
  }
}
4

1 に答える 1

5

ThreadPoolExecutorを再発明しました!

Java 7を使用しているので、新しいフォーク結合APIを使用したくなるでしょうが、あなたの場合はThreadPoolExecutorが必要なものであると確信しています。

于 2012-06-06T23:42:25.777 に答える