java.util.ConcurrentModificationException异常原因及解决方法

今天在做一个很简单的Java练习题的时候遇到这个问题。

题目:一对兔子在出生第三个月的时候开始,每个月会生一对小兔子。当小兔子在它们第三个月的时候,同理。问:每个月的兔子总数。

这是一个很简单的题,前6个月的兔子数量是,1,1,2,3,5,8.斐波拉契数列。按这个规律就可以得出结果。但是我是用创建对象的方法来做。

代码:

1public class Main { 2 3 private static List<Rabbit> mList = new CopyOnWriteArrayList<>(); 4 5 public static void main(String[] args) { 6 Rabbit r1 = new Rabbit(0); 7 mList.add(r1); 8 for (int i = 0; i < 10; i++) { 9 for(Rabbit r:mList){ 10 if (r.getAge()>=2){ 11 mList.add(r.born()); 12 } 13 r.grow(); 14 } 15 System.out.println("第"+i+"个月, 兔子数量:"+mList.size()+"对"); 16 } 17 } 18 19 20} 21 22public class Rabbit { 23 24 private int age ;//以月为单位 25 26 public Rabbit(int age) { 27 this.age = age; 28 } 29 30 public int getAge() { 31 return age; 32 } 33 34 public void setAge(int age) { 35 this.age = age; 36 } 37 38 public Rabbit born(){ 39 if (age>=2){ 40 return new Rabbit(1); 41 } 42 return null; 43 } 44 45 public void grow(){ 46 setAge(age+=1); 47 } 48 49 @Override 50 public String toString() { 51 return "[年龄:"+age+"个月]"; 52 } 53}

最开始我没有用CopyOnWriteArrayList这个类,我就用的ArrayList.然后就报题目中的异常了。然后网上一查,才知道,ArrayList在读的时候,不能同时进行增删。可以从源码中去查看。然后CopyOnWriteArrayList这个类,是在写时拷贝,也就是如果需要对CopyOnWriteArrayList的内容进行改变,首先会拷贝一份新的List并且在新的List上进行修改,最后将原List的引用指向新的List。使用CopyOnWriteArrayList可以线程安全地遍历,因为如果另外一个线程在遍历的时候修改List的话,实际上会拷贝出一个新的List上修改,而不影响当前正在被遍历的List。

如果是HashMap使用“ConcurrentHashMap”替换HashMap,ConcurrentHashMap会自己检查修改操作,对其加锁,也可针对插入操作。

ps:这个小题目,我在兔子年龄上花了不少时间,把我自己搞晕了。实际上是在它们第2个月完,第3个月开始就开始生产了。

点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java基础编程练习题

1、題目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?123456711235813这就是斐波那契数列(Fibonaccisequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Le

java经典50题

JAVA基础编程练习50题本文对50道经典的java程序题进行详细解说,对于初学者可以跳过一些逻辑性太强的题目,比如第一题用到了方法的递归,初学者可能不理解,最好先看那些有if、for、while可以简单解决的程序题!但是,对于比较深入学习过的同学,还是希望可以一口气就看完,这是比较全面思维锻炼!【程序1】题目:古典问题:有一对兔子,从

C语言基础习题50例(三)11-15

你们看出神马了吗(\\^_\^\)习题11有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少实现思路:从第1个月起,兔子对数分别为1、1、2、3、5、8、13、21...,显然是斐波拉契数列。代码如下:cinclude<stdio.hintmai

Java面试不得不知的程序(二)

【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?斐波那契数列:前面相邻两项之和,构成了后一项通项公式注:此时a11,a21,ana(n1)a(n2)(n3,n∈N\)通项公式的推导斐波那契数列:1、1

Python递归函数、匿名函数、过滤函数

递归函数Python对递归的深度有限制,超过即会报错。所以一定一要注意跳出条件。斐波拉契数列一个数列,第一个数是1,第二个数也是1,从第三个数开始,每一个数是前两个数之和公式:f(1)1,f(2)1,f(3)f(1)f(2),...,f(n)f(n2)f(n1)