所以我正在上课。该计划的目的是让一些人从袋子里吃水果。水果给予能量,人的能量每秒都在减少。我遇到的问题是,每次吃水果,我都会做一个看起来像这样的输出:
System.out.println("There are now " + fruitList.size() + " fruits left in the bag.");
据我所知,这应该输出我的arraylist的当前大小。令我困惑的是,如果两个人(通过两个不同的线程初始化)大约在同一时间进食,这应该首先显示,“现在袋子里还剩下10个水果。”,然后“那里现在已经把9个水果留在了包里。“问题是这两条消息都会显示有10个结果。
这是Person类中负责此操作的方法:
public void eat(Fruit fruit, ArrayList<Fruit> fruitList, MagicBag magicBag) {
lock.lock();
try {
while (getEnergy() > 20) {
newDeposit.await();
}
if(energy < 30 && energy > 20) {
System.out.println(this.getName() + " is getting hungry.");
} else {
System.out.println(this.getName() + " picked a " + fruitList.get(fruitList.size() - 1).getName() + " and started to eat...");
Thread.sleep(1000);
int fruitEnergy;
fruitEnergy = fruitList.get(fruitList.size() - 1).getEnergyValue();
fruitList.remove(fruitList.size() - 1);
if(energy > 100) {
energy = 100;
} else {
energy += fruitEnergy;
}
System.out.println(this.getName() + " ate a " + fruitList.get(fruitList.size() - 1).getName() + "!");
System.out.println("There are now " + fruitList.size() + " fruits left in the bag.");
magicBag.addFruitsToBag(fruitList, fruit);
newDeposit.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
这就是run()在实现运行上述代码的Runnable的类中所做的事情:
public void run() {
// TODO Auto-generated method stub
try {
while(running) {
if(fruitList.size() > 0) {
person.eat(fruit, fruitList, magicBag);
Thread.sleep(1000);
}
else {
kill();
}
}
} catch(InterruptedException e) {
e.printStackTrace();
} catch(IndexOutOfBoundsException ie) {
running = false;
} catch(NullPointerException ne) {
ne.printStackTrace();
}
}
所以,如果有人能帮助我那将是非常棒的。如果您还需要其他任何东西,请询问。
答案 0 :(得分:3)
fruitList
上没有内存障碍,因此您的线程同时检查和修改同一个对象。您需要在fruitList
上进行同步(在这种情况下最好,因为这是共享的资源)或使用其他一些机制来确保存在内存障碍,例如使用并发集合。