我想创建一个简单的模拟,我需要一个线程池,所以我决定写一个。我的界面如下:
public interface ThreadPool {
public void start();
public int getTaskListSize();
public void addTask(Task task);
public Task getNextTask();
}
最重要的部分是任务列表的大小有限,当有人试图在完成时向其添加任务时,他被阻止并等待此对象。然而,通过我的实现,想要getNextTask的线程通过notifyAll调用相互唤醒,这很糟糕。
@Override
public void addTask(Task task) {
synchronized (tasks) {
tasks.add(task);
log("task list size:" + tasks.size());
}
synchronized (this) {
notifyAll();
}
}
@Override
public Task getNextTask() {
Task task;
synchronized (tasks) {
task = tasks.poll();
}
synchronized (this) {
notifyAll();
}
return task;
}
有没有一种干净的方法来解决这个问题?我使用ArrayBlockingQueue来保存任务。
从线程调用addTask是:
protected void addTask(Task task, ThreadPool threadPool) {
while (true) {
try {
log("trying to add " + task);
threadPool.addTask(task);
log("added " + task +"!");
return;
} catch (IllegalStateException ex) {
log("adding failed, waiting");
synchronized(threadPool) {
threadPool.wait()
}
}
}
}