我目前正在尝试实现一个可以在几个不同线程中运行的系统列表:
1) 第一个线程正在监听传入请求并将它们添加到列表中。
2)为每个请求创建一个新线程来执行某些操作。
3) 另一个线程遍历列表,检查每个请求的状态,并在完成后将其从列表中删除。
现在,我可以在下面查看非常简化的伪代码的方式:
private List<Job> runningJobs = new ArrayList<>(); // our list of requests
private Thread monitorThread;
private Runnable monitor = new Runnable() { // this runnable is later called in a new thread to monitor the list and remove completed requests
@Override
public void run() {
boolean monitorRun = true;
while(monitorRun) {
try {
Thread.sleep(1000);
if (runningJobs.size()>0){
Iterator<Job> i = runningJobs.iterator();
while (i.hasNext()) {
try {
Job job = i.next();
if (job.jobStatus() == 1) { // if job is complete
i.remove();
}
}
catch (java.util.ConcurrentModificationException e){
e.printStackTrace();
}
}
}
if (Thread.currentThread().isInterrupted()){
monitorRun = false;
}
} catch (InterruptedException e) {
monitorRun = false;
}
}
}
};
private void addRequest(Job job){
this.runningJobs.add(newJob);
// etc
}
简单来说,Runnable监视器就是在第三个线程中持续运行的;第一个线程偶尔调用 addRequest()。
虽然我当前的实现在某种程度上有效,但我担心这里的操作顺序和可能的 java.util.ConcurrentModificationException (并且系统根本不健壮)。我确信有更好的方法来整理这个困惑的局面。
正确或更好的方法是什么?
最佳答案
ExecutorService 可以很好地满足您的要求。对于每个请求,创建Job
,并将其提交到服务。在内部,该服务使用 BlockingQueue
,它可以直接解决您的问题,但您不必使用 ExecutorService
担心它。
具体来说,是这样的:
/* At startup... */
ExecutorService workers = Executors.newCachedThreadPool();
/* For each request... */
Job job = ... ;
workers.submit(job); /* Assuming Job implements Runnable */
// workers.submit(job::jobEntryPoint); /* If Job has some other API */
/* At shutdown... */
workers.shutdown();
关于java - 实现必须从不同线程添加/删除元素的元素列表的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50766116/