我对于Java还是很陌生,正在从事一个项目来在Java中模拟CPU scheduler
,并且我正在使用linked list
存储从外部主列表中读取的每个过程对象。当我测试打印过程及其包含的变量时,一切都会按预期进行,但是只要我尝试对其进行操作,它就会停止工作。
public class process
String ID;
int Arrive;
int ExecSize;
int Execstore;
int Tstart;
int Tend;
int quant;
public process(String ID,int Arrive,int ExecSize) {
this.ID = ID;
this.Arrive = Arrive;
this.ExecSize = ExecSize;
this.Execstore=ExecSize;
this.Tend = 0;
this.Tstart = 0;
this.quant = 4;
}
public void setquant(int update) {
this.quant = update;
}
public int getquant() {
return quant;
}
public void setExecSize(int update) {
this.ExecSize = update;
}
public void setTend(int update) {
this.Tend = update;
}
public void setTstart(int update) {
this.Tstart = update;
}
String getID() {
return ID;
}
int getArrive() {
return Arrive;
}
int getExecSize() {
return ExecSize;
}
int getTstart() {
return Tstart;
}
int getTend() {
return Tend;
}
int getExecstore() {
return Execstore;
}
这是用于仿真的类
public class fcfs {
int disp;
int Ttotal = 0;
int Exec;
int Turn;
int Wait;
String output;
LinkedList<process> Que = new LinkedList<process>();
LinkedList<process> Quecleared = new LinkedList<process>();
public fcfs(LinkedList<process> B,int D) {
Que.addAll(B);
disp=D;
}
public void run()
{
while (Que != null)
{
Ttotal = Ttotal + disp;
System.out.println(Que.getFirst().getExecSize());
Exec=Que.getFirst().getExecSize();
output += String.format("T%d: %s\n",Ttotal,Que.getFirst().getID());
Que.getFirst().setTstart(Ttotal);
Ttotal = Ttotal+Exec;
Que.getFirst().setTend(Ttotal);
Quecleared.add(Que.poll());
}
}
因此,每当我使用System.out.println
时,我都会得到读入列表的预期结果。但是我尝试参考流程对象的元素进行的任何其他操作均不起作用。任何帮助将不胜感激
答案 0 :(得分:0)
while (!Que.isEmpty())
{
Ttotal = Ttotal + disp;
System.out.println(Que.peekFirst().getExecSize());
Exec=Que.peekFirst().getExecSize();
output += String.format("T%d: %s\n",Ttotal,Que.peekFirst().getID());
Que.peekFirst().setTstart(Ttotal);
Ttotal = Ttotal+Exec;
Que.peekFirst().setTend(Ttotal);
Quecleared.add(Que.pollFirst());
}
这不应在Exec = Que.peekFirst().getExecSize();
上引发错误
当您的容器为空时,抛出该错误。
编辑
您在代码中指定了条件Que != null
。在Java中,一旦实例化了对象,即使它是null
,也不再被认为是empty
。很有可能发生在这里,是您继续遍历while(Que != null)
循环,直到对列表的所有元素调用了Que.poll()
。
清除列表后,您没有退出循环,因为Que
仍然不是null
。然后在getFirst()
的空实例上调用LinkedList
引发异常。
在这里可以看到类似的情况,即空字符串与空字符串: Difference between null and empty ("") Java String
编辑2
看来,getID()
,getExecSize()
等的类方法正在通过引用传递值,而不是复制它们的值。因此,您从队列传递引用后所做的任何更改都会更改您尝试对其进行的任何副本。
最好通过创建对象的新实例并将其从函数中返回来避免这种情况。在有关以下链接的问题的答案中显示:
class Foo {
private Bar myBar;
public Foo deepCopy() {
Foo newFoo = new Foo();
newFoo.myBar = myBar.clone(); //or new Bar(myBar) or myBar.deepCopy or ...
return newFoo;
}
}
有关通过values
(而不是先前存在的实例的reference values
)传递方式的更多信息,以及实际上是什么浅表副本,请查看以下链接:In Java, what is a shallow copy? < / p>