2012-06-06 23 views
1

我的问题是:什么是“最佳”方法来控制多个“RunnableObject s”的列表?使用多个对象列表对同一对象进程进行线程处理

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

你为什么重新发明轮子?这是作业还是仅用于个人教育?你不能使用'java.util.concurrent'中的类吗? –

+0

未完成作业:)个人教育。我发现自己总是需要这样做。 – kentcdodds

+2

如果你还没有研究'java.util.concurrent',我强烈建议你这样做。如果你有,它会帮助你更新你的文章,解释为什么这个框架不会做你想做的。 –

回答

5

您刚刚重塑了ThreadPoolExecutor

由于您使用的是Java 7,所以使用新的fork join API会很诱人,但我非常确定,在您的情况下,ThreadPoolExecutor就是您所需要的。

+0

谢谢,我正在研究它。到现在为止还挺好。 – kentcdodds

+0

在你的情况下,相当于Executors.newFixedThreadPool(10);这将创建10个线程来执行你的 – tibo

相关问题