线程中的异常 "main" java.util.ConcurrentModificationException(Head first java 书本示例)
Exception in thread "main" java.util.ConcurrentModificationException (Head first java book example)
我尝试 运行 Head first java 一书的示例 - 第二版(第 152 页)。这是一个游戏谜题。它以网格中的 Dotcoms(string) 为目标来击沉它们。但是当我尝试 运行 这个谜题时,我得到了一个 Java.util.concurrentModificationException 错误。当我试图在网格中沉没最后一个 dotCom(String) 时,我才遇到这个错误。假设我在网格中有三个字符串,如下图所示。因此,当我开始提供输入时,我能够删除(命中)前两个字符串(因为它们添加到 arrayList 中)但是当我尝试删除最后一个字符串(最后添加到 Arraylist 中的字符串)时,然后得到 concurrentmodificationException 错误。下面给出了示例代码和控制台日志。
那么为什么我会收到这个错误以及如何消除这个错误。
class DotComBust{
private GameHelper helper = new GameHelper();
private ArrayList<DotCom> dotComList = new ArrayList<DotCom>();
private int numofguesses=0;
private void setUpGame(){
DotCom one = new DotCom();
one.setNames("Pets.com");
DotCom two = new DotCom();
two.setNames("eToys.com");
DotCom three = new DotCom();
three.setNames("Go2.com");
dotComList.add(one);
dotComList.add(two);
dotComList.add(three);
System.out.println("your goal is sunk three dot coms");
System.out.println("Pets.com, eToys.com, Go2.com");
System.out.println("Try to sink them all in fewest number of guesses");
for(DotCom dotComToSet : dotComList){
ArrayList<String> newLocation = helper.placeDotCom(3);
dotComToSet.setLocationCells(newLocation);
}
}
private void startPlaying(){
while(!dotComList.isEmpty()){
String userGuess = helper.getUserInput("Enter a guess");
checkUserGuess(userGuess);
}
finishGame();
}
private void checkUserGuess(String userGuess){
numofguesses++;
String result = "miss";
for(DotCom dotComToTest : dotComList){
result = dotComToTest.checkYourself(userGuess);
if(result.equals("hit")){
break;
}
if(result.equals("kill")){
dotComList.remove(dotComToTest);
}
}
System.out.println(result);
}
private void finishGame(){
System.out.println("All the dotcoms are dead your stock is worthless");
if(numofguesses<=18){
System.out.println("It only took you" + numofguesses + "guesses");
System.out.println("You got out before your option sank");
}else{
System.out.println("Took you long enough" + numofguesses + "guesses");
System.out.println("Fish are dancing with your option");
}
}
public static void main(String[] args) {
DotComBust game = new DotComBust();
game.setUpGame();
game.startPlaying();
}
}
错误
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at DotComBust.checkUserGuess(DotComBust.java:77)
at DotComBust.startPlaying(DotComBust.java:68)
at DotComBust.main(DotComBust.java:106)
因为当你循环一个集合时
while(!dotComList.isEmpty()){
String userGuess = helper.getUserInput("Enter a guess");
checkUserGuess(userGuess);
}
您不能修改列表的内容,但在您的方法 checkUserGuess 中,您正试图从列表中删除元素
if(result.equals("kill")){
dotComList.remove(dotComToTest);
}
这就是导致 ConcurrentModificationException 的原因
我假设你可能同时有另一个绘图线程运行?
在这种情况下,使用名为 CopyOnWriteArrayList
:
的 List
的线程安全实现
private ArrayList<DotCom> dotComList = new CopyOnWriteArrayList<DotCom>();
我尝试 运行 Head first java 一书的示例 - 第二版(第 152 页)。这是一个游戏谜题。它以网格中的 Dotcoms(string) 为目标来击沉它们。但是当我尝试 运行 这个谜题时,我得到了一个 Java.util.concurrentModificationException 错误。当我试图在网格中沉没最后一个 dotCom(String) 时,我才遇到这个错误。假设我在网格中有三个字符串,如下图所示。因此,当我开始提供输入时,我能够删除(命中)前两个字符串(因为它们添加到 arrayList 中)但是当我尝试删除最后一个字符串(最后添加到 Arraylist 中的字符串)时,然后得到 concurrentmodificationException 错误。下面给出了示例代码和控制台日志。
那么为什么我会收到这个错误以及如何消除这个错误。
class DotComBust{
private GameHelper helper = new GameHelper();
private ArrayList<DotCom> dotComList = new ArrayList<DotCom>();
private int numofguesses=0;
private void setUpGame(){
DotCom one = new DotCom();
one.setNames("Pets.com");
DotCom two = new DotCom();
two.setNames("eToys.com");
DotCom three = new DotCom();
three.setNames("Go2.com");
dotComList.add(one);
dotComList.add(two);
dotComList.add(three);
System.out.println("your goal is sunk three dot coms");
System.out.println("Pets.com, eToys.com, Go2.com");
System.out.println("Try to sink them all in fewest number of guesses");
for(DotCom dotComToSet : dotComList){
ArrayList<String> newLocation = helper.placeDotCom(3);
dotComToSet.setLocationCells(newLocation);
}
}
private void startPlaying(){
while(!dotComList.isEmpty()){
String userGuess = helper.getUserInput("Enter a guess");
checkUserGuess(userGuess);
}
finishGame();
}
private void checkUserGuess(String userGuess){
numofguesses++;
String result = "miss";
for(DotCom dotComToTest : dotComList){
result = dotComToTest.checkYourself(userGuess);
if(result.equals("hit")){
break;
}
if(result.equals("kill")){
dotComList.remove(dotComToTest);
}
}
System.out.println(result);
}
private void finishGame(){
System.out.println("All the dotcoms are dead your stock is worthless");
if(numofguesses<=18){
System.out.println("It only took you" + numofguesses + "guesses");
System.out.println("You got out before your option sank");
}else{
System.out.println("Took you long enough" + numofguesses + "guesses");
System.out.println("Fish are dancing with your option");
}
}
public static void main(String[] args) {
DotComBust game = new DotComBust();
game.setUpGame();
game.startPlaying();
}
}
错误
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at DotComBust.checkUserGuess(DotComBust.java:77)
at DotComBust.startPlaying(DotComBust.java:68)
at DotComBust.main(DotComBust.java:106)
因为当你循环一个集合时
while(!dotComList.isEmpty()){
String userGuess = helper.getUserInput("Enter a guess");
checkUserGuess(userGuess);
}
您不能修改列表的内容,但在您的方法 checkUserGuess 中,您正试图从列表中删除元素
if(result.equals("kill")){
dotComList.remove(dotComToTest);
}
这就是导致 ConcurrentModificationException 的原因
我假设你可能同时有另一个绘图线程运行?
在这种情况下,使用名为 CopyOnWriteArrayList
:
List
的线程安全实现
private ArrayList<DotCom> dotComList = new CopyOnWriteArrayList<DotCom>();