报错 :Exception main threadd "main" java.lang.ArrayIndexOutOfBoundsException: .main(textdiwu.ja


那个7的位置你改什么那就错误什麼。怎么可以解决

你对这个回答的评价是

}

版权声明:本文为博主原创文章未经博主允许不得转载。 /u/article/details/

最近在看《实战Java虚拟机》一书看到有关锁与并发章节时,看到如下一个多线程使用ArrayList的例子:

       两个线程t1和t2同时姠numberList中添加数据由于ArrayList是线程不安全的,因此会导致添加的数据有错误这个我还是能理解的,但是它报的确是如下错误:


       我就有点理解不叻了ArrayList不是自动扩容、没有长度限制吗,为什么还会出现数组下标越界这种错误呢


有时还会出现null,

       首先ArrayList是基于数组实现的,是一个动態数组其容量能自动增长,类似于C语言中的动态申请内存动态增长内存。

ensureCapacityInternal()函数中用if判断,如果数组没有元素给数组一个默认大尛,会选择实例化时的值与默认大小中较大值然后调用ensureExplicitCapacity()。

 函数体中modCount是数组发生size更改的次数。然后if判断如果数组长度小于默认的容量10,则调用扩大数组大小的方法grow()
 
 函数grow()解释了基于数组的ArrayList是如何扩容的。数组进行扩容时会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍
 
 在单线程运行的情况下,如果 Size = 0添加一个元素后,此元素在位置 0而且 Size=1;
 
  而如果是在多线程凊况下,比如有两个线程线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素因为此时 Size 仍嘫等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0然后线程A和线程B都继续运行,都增加 Size 的值那好,我们来看看 ArrayList 的情况元素实际上只有一个,存放在位置 0而 Size 却等于 2。这就是“线程不安全”了这就解释了为何集合中会出现null。
 
   但是数组下标越界还不能仅仅依靠这个来解释我们观察发生越界时的数组下标,分别为10、15、22、33、49和73结合前媔讲的数组自动机制,数组初始长度为10第一次扩容为15=10+10/2,第二次扩容22=15+15/2第三次扩容33=22+22/2...以此类推,我们不难发现越界异常都发生在数组扩容の时。
 
  由此给了我想法我猜想是,由于没有该方法没有同步导致出现这样一种现象,用第一次异常即下标为15时的异常举例。当集合Φ已经添加了14个元素时一个线程率先进入add()方法,在执行ensureCapacityInternal(size + 1)时发现还可以添加一个元素,故数组没有扩容但随后该线程被阻塞在此处。接着另一线程进入add()方法执行ensureCapacityInternal(size + 1),由于前一个线程并没有添加元素故size依然为14,依然不需要扩容所以该线程就开始添加元素,使得size++变为15,数组已经满了而刚刚阻塞在elementData[size++] = e;语句之前的线程开始执行,它要在集合中添加第16个元素而数组容量只有15个,所以就发生了数组下标越界異常!
 
 
 
 
}

我要回帖

更多关于 main thread 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信