龙空技术网

ArrayList线程不安全的案例分析

万物生的好物 311

前言:

今天咱们对“javaweb线程安全问题”都比较着重,同学们都想要了解一些“javaweb线程安全问题”的相关资讯。那么小编也在网络上收集了一些对于“javaweb线程安全问题””的相关文章,希望咱们能喜欢,我们快快来了解一下吧!

在java的项目开发中,我们工作中使用最多的集合应该就是ArrayList了,

但是你可知ArrayList是线程不安全的,平时我们使用时都是单线程或者线程数比较少的情况,

这种情况ArrayList一般都不会出现问题,但是线程一旦多起来,问题就很容易爆发了

如下面的多线程案例

import java.util.ArrayList;import java.util.List;import java.util.concurrent.CountDownLatch;public class ListTest {    private static final int threadNum = 20;        static List list =new ArrayList();    static CountDownLatch latch = new CountDownLatch(20);        public static void main(String[] args) {                for (int i = 0; i < threadNum; i++) {            Thread thread = new Thread(new Runnable() {                @Override                public void run() {                    for (int i = 0; i < 1000; i++) {                        list.add(i);                    }                    latch.countDown();                }            });            thread.start();        }                try {			latch.await();//等待所有线程完成		} catch (InterruptedException e) {			e.printStackTrace();		}        System.out.println("list中总数量===="+list.size());    }}

正常结果应该打印20000,可是每次运行的结果确实抛出异常java.lang.ArrayIndexOutOfBoundsException

这是什么原因呢?

这是因为ArrayList底层是数组,每次add时,执行 element[i++]=a,

而element[i++]=a在cup层是分两步进行的

1. element[i]=a

2. i=i+1

但由于多线程运行时,假设数组的长度一开始等于2,i等于1,数组还剩一个元素可放入,A线程刚进入add方法时,还没来得及执行步骤1, cup就让他暂停,此时线程B运行了,依然是i=1,执行1、2步骤后,i变成了2,

等到A线程运行1时,element[2]=a 就发生越界了。

这就是线程不安全了,假设线程在进入add之前就已经发现数组长度不够,ArrayList就会进行扩容,就不会发生这种情况了

怎么解决呢

这就是本次的主角Vector上场了

只需要就static List list =new ArrayList();换成 static List list =new Vector();就可以保证线程安全了

标签: #javaweb线程安全问题