这为什么会报错(多线程或ArrayList)?

huangapple go评论90阅读模式
英文:

Why does this gives me an error (Multi Thread or ArrayList)?

问题

  1. ArrayList<Nemico> nemici = o_orda.getNemici();
  2. for (Nemico nemico : nemici) {
  3. if (Collisioni.ControllaCollisioni(o_navicella, nemico)) {
  4. nemici.remove(nemico);
  5. this.o_navicella.vita -= 10;
  6. break;
  7. }
  8. for (Proiettile pro : proiettili) {
  9. System.out.println("s1");
  10. if (Collisioni.CollsioniProiettile(pro, nemico)) {
  11. System.out.println("s2");
  12. nemici.remove(nemico);
  13. System.out.println("s3");
  14. proiettili.remove(pro);
  15. System.out.println("s4");
  16. break;
  17. }
  18. System.out.println("s5");
  19. }
  20. if (ControllaSconfitta()) {
  21. this.giocON = false;
  22. Disegna();
  23. }
  24. }

This is the code, I'm sure it will help you.
This code is in a function that checks and updates everything every n milliseconds.

Thanks for the help

  1. Exception in thread "Thread-7" java.util.ConcurrentModificationException
  2. at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
  3. at java.util.ArrayList$Itr.next(ArrayList.java:851)
  4. at java.lang.Thread.run(Thread.java:745)

and it freezes the game when the collision happens.

  1. <details>
  2. <summary>英文:</summary>
  3. I have two threads which are running and I need to control if the bullet is touching the enemy but it gives me this problem where I printed &quot;s4&quot;. Any idea what happened there? I&#39;m quite a beginner. I&#39;m using Java.

ArrayList<Nemico> nemici= o_orda.getNemici();
for (Nemico nemico : nemici) {
if(Collisioni.ControllaCollisioni(o_navicella, nemico)){
nemici.remove(nemico);
this.o_navicella.vita-=10;

  1. break;
  2. }
  3. for (Proiettile pro : proiettili){
  4. System.out.println(&quot;s1&quot;);
  5. if(Collisioni.CollsioniProiettile(pro, nemico)){
  6. System.out.println(&quot;s2&quot;);
  7. nemici.remove(nemico);
  8. System.out.println(&quot;s3&quot;);
  9. proiettili.remove(pro);
  10. System.out.println(&quot;s4&quot;);
  11. break;
  12. }
  13. System.out.println(&quot;s5&quot;);
  14. }
  15. if(ControllaSconfitta()){
  16. this.giocON=false;
  17. Disegna();
  18. }
  19. }
  1. This is the code, I&#39;m sure it will help you.
  2. This code is in a function that checks and update everything every n millisecond.
  3. Thanks for the help

Exception in thread "Thread-7" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at java.lang.Thread.run(Thread.java:745)

  1. and it freeze the game when the collsion happens.
  2. </details>
  3. # 答案1
  4. **得分**: 1
  5. _以下代码已经更新以使用Iterator.remove(),而不是ArrayList.remove()。感谢@PeterRader澄清了它们的使用方法。_
  6. ---
  7. 如果您在迭代ArrayList时打算对其进行修改,不应直接使用for-each循环进行迭代。有两种替代方法,一种是使用迭代器避免直接迭代ArrayList本身,另一种是使用Java 8removeIf()函数。
  8. 我将给出一个简单(经过测试的)使用迭代器的示例,然后尝试修改您的代码以执行相同的操作:
  9. **迭代器示例**
  10. ```java
  11. import java.util.ArrayList;
  12. import java.util.Arrays;
  13. import java.util.Iterator;
  14. public class IteratorExample {
  15. public static void main(String[] args) {
  16. ArrayList<Integer> arrList = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
  17. // 获取一个迭代器以迭代arrList中的整数
  18. Iterator<Integer> iterator = arrList.iterator();
  19. // 当迭代器有下一个元素时,使用.next()访问此元素并将其打印出来。
  20. while (iterator.hasNext()) {
  21. System.out.println(iterator.next());
  22. }
  23. }
  24. }

修改您的代码以使用迭代器

对于此版本中可能存在的拼写错误或语法错误,我深感抱歉 - 我无法对其进行测试,但鉴于这只是一个小片段的代码,错误应该不会太多,希望您可以使用上述示例进行修复。 不要忘记也导入java.util.Iterator!

  1. ArrayList<Nemico> nemici = o_orda.getNemici();
  2. Iterator<Nemico> nemiciIterator = nemici.iterator();
  3. while (nemiciIterator.hasNext()) {
  4. nemico = nemiciIterator.next();
  5. if (Collisioni.ControllaCollisioni(o_navicella, nemico)) {
  6. nemiciIterator.remove();
  7. this.o_navicella.vita -= 10;
  8. break;
  9. }
  10. Iterator<Proiettile> proIterator = proiettili.iterator();
  11. while (proIterator.hasNext()) {
  12. pro = proIterator.next();
  13. if (Collisioni.CollsioniProiettile(pro, nemico)) {
  14. nemiciIterator.remove();
  15. proIterator.remove();
  16. break;
  17. }
  18. }
  19. if (ControllaSconfitta()) {
  20. this.giocON = false;
  21. Disegna();
  22. }
  23. }
  24. ...

资源

这是一个相关的资源。它还包括使用removeIf()的示例!https://www.baeldung.com/java-concurrentmodificationexception

英文:

The below code has been updated to use Iterator.remove() instead of ArrayList.remove(). Thank you to @PeterRader for clarifying how these should be used.


If you are intending to modify an ArrayList while iterating over it, you should not use a for-each loop to iterate over it directly. There are two alternative approaches, using an iterator to avoid iterating over the ArrayList itself, or using Java 8's removeIf() function.

I will give a simple (and tested) example of using an iterator, and then attempt to modify your code to do the same thing:

Iterator Example

  1. import java.util.ArrayList;
  2. import java.util.Arrays;
  3. import java.util.Iterator;
  4. public class IteratorExample{
  5. public static void main(String []args){
  6. ArrayList&lt;Integer&gt; arrList = new ArrayList&lt;Integer&gt;(Arrays.asList(1,2,3));
  7. // Get an Iterator to iterate over the Integers in arrList
  8. Iterator&lt;Integer&gt; iterator = arrList.iterator();
  9. // While iterator hasNext element, access this element with .next() and print it.
  10. while(iterator.hasNext()) {
  11. System.out.println(iterator.next());
  12. }
  13. }
  14. }

Modifying your code to use an iterator

Apologies for any spelling mistakes or syntax errors in this version - I have been unable to test it, but given it's only a small piece of code there shouldn't be many and hopefully you will be able to remedy them using the example above. Don't forget to import java.util.Iterator too!

  1. ArrayList&lt;Nemico&gt; nemici= o_orda.getNemici();
  2. Iterator&lt;Nemico&gt; nemiciIterator = nemici.iterator();
  3. while (nemiciIterator.hasNext()) {
  4. nemico = nemiciIterator.next();
  5. if(Collisioni.ControllaCollisioni(o_navicella, nemico)){
  6. nemiciIterator.remove(nemico);
  7. this.o_navicella.vita-=10;
  8. break;
  9. }
  10. Iterator&lt;Proiettile&gt; proIterator = proiettili.iterator();
  11. while (proIterator.hasNext()) {
  12. pro = proIterator.next();
  13. if(Collisioni.CollsioniProiettile(pro, nemico)){
  14. nemiciIterator.remove(nemico);
  15. proIterator.remove(pro);
  16. break;
  17. }
  18. }
  19. if(ControllaSconfitta()){
  20. this.giocON=false;
  21. Disegna();
  22. }
  23. }
  24. ...

Resources

Here is a relevant resource. This also includes an example of using removeIf()! https://www.baeldung.com/java-concurrentmodificationexception.

huangapple
  • 本文由 发表于 2020年3月15日 07:02:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/60688124.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定