【问题标题】:Threading the same object process with a list of many objects使用许多对象的列表线程化相同的对象进程
【发布时间】:2012-06-07 07:46:34
【问题描述】:

我的问题是:控制线程化许多“RunnableObjects”列表的“最佳”方法是什么?

我有一种处理多线程的方法,但我认为它不是最佳的。在很多情况下,我有一个对象列表,它们都需要做同样的事情,但我不希望它们一次只做一个,所以我将它们放在一个列表中,并将其中一些线程放在一次。完成后,它会在控制器上调用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;
  }
}

【问题讨论】:

  • 为什么要重新发明轮子?这是作业还是仅用于个人教育? java.util.concurrent中的类不能用吗?
  • 不是家庭作业 :) 个人教育。我发现自己一直需要做这样的事情。
  • 如果你还没有学过java.util.concurrent我强烈建议你这样做。如果你有,它会帮助你更新你的帖子,解释为什么这个框架不能做你想要的。
  • 我没有研究过java.util.concurrent,谢谢你的提示,我会研究一下。

标签: java multithreading optimization


【解决方案1】:

您刚刚重新发明了ThreadPoolExecutor!

由于您使用的是 java 7,因此很想使用新的 fork join API,但我很确定在您的情况下,ThreadPoolExecutor 就是您所需要的。

【讨论】:

  • 在你的情况下,相当于 Executors.newFixedThreadPool(10);这将创建 10 个线程来执行你的
猜你喜欢
  • 1970-01-01
  • 2016-04-18
  • 2014-11-29
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
相关资源
最近更新 更多