【发布时间】:2020-03-29 16:39:13
【问题描述】:
我目前正在尝试编写一个将客户发送到最短队列的应用程序。每个队列都有自己的线程。
在 Queue 类中,我有一个实例变量 nrClients,用于跟踪队列中有多少客户端。
在 run 方法中,我有一个 while 条件,仅当 nrClients 大于 0 时才保持线程运行,但有时即使 nrClients 为 0,它也会进入该 while 循环,从而在代码中触发 NullPointerException在那段时间里面。我还有一个从0 到nrClients-1 的for 循环,但有时它会进入该循环并给我一个Index 0 out of bounds for length 0 异常。这是我在该课程中编写的代码:
public class Queue implements Runnable{
BlockingQueue<Client> queue;
private int nrClients;
private AtomicInteger waitTime;
private boolean isClosed=true;
public Queue(){
nrClients= 0;
waitTime = new AtomicInteger(0);
queue = new LinkedBlockingQueue<Client>();
}
public void addClient(Client c){
nrClients++;
queue.add(c);
waitTime.addAndGet(c.getServiceTime());
c.setWaitTime(waitTime.get());
}
private void removeClient(Client c){
nrClients--;
queue.remove();
}
@Override
public void run() {
while (nrClients>0) {
isClosed = false;
Client c = queue.peek();
try {
int mustWait = c.getServiceTime();
for (int i = 0; i < mustWait; i++) {
Thread.sleep(10);
c.decServiceTime();
waitTime.decrementAndGet();
}
} catch (InterruptedException e) {
}
removeClient(c);
}
if (nrClients == 0)
isClosed = true;
}
public AtomicInteger getWaitTime() {
return waitTime;
}
public String toString(){
if(nrClients==0){
return "closed";
}
else
{
String r="";
for(int i=0; i<nrClients; i++){
Client c = (Client) queue.toArray()[i];
r+="("+c.getID()+","+c.getArrivalTime()+","+c.getServiceTime()+"); ";
}
return r;
}
}
public boolean isClosed() {
return isClosed;
}
我似乎找不到导致这些异常的问题,如果您能指出问题所在,我将不胜感激。提前谢谢!
编辑:我试过让 nrClients volatile / AtomicInteger,都没有解决问题。此外,通过用 queue.size() 替换 nrClients,我仍然会在 toString 方法中包含的 for 循环中获得索引异常。
【问题讨论】:
-
我已经尝试过 queue.size() 但它仍然在那个 for 循环中遇到异常,索引 0 超出了长度 0 的范围
-
请注意增量运算符不是线程安全的。
标签: java multithreading