ArrayList测试线程不安全时会抛出异常

来源:5-5 线程不安全类与写法-2

qq_超人不会飞_22

2019-08-13

在线程不安全类与写法这一节测试ArrayList时遇到问题,代码如下,和老师的一样,没什么区别:
public class ArrayListExample {
//请求总数
public static int clientTotal = 5000;
//同时并发执行的线程数
public static int threadLocal = 200;

public static List<Integer> list = new ArrayList<>();

public static void main(String[] args) throws InterruptedException{
    //定义线程池
    ExecutorService executorService = Executors.newCachedThreadPool();
    //定义信号量,允许并发的数目为200
    final Semaphore semaphore = new Semaphore(threadLocal);
    //定义CountDownLatch
    final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);

    for (int i = 0; i < clientTotal; i++) {
        final int count = i;
        //将所有请求放入到线程池中执行
        executorService.execute(() ->{
            try {
                semaphore.acquire();
                update(count);
                semaphore.release();
            } catch (InterruptedException e) {
                log.error("InterruptedException",e);
            }
            //线程每执行完一次add操作时,就调用countDownLatch
            countDownLatch.countDown();
        });
    }
    //保证countDownLatch的值为0,即所有的线程都执行完毕
    countDownLatch.await();
    //关闭线程池
    executorService.shutdown();
    log.info("list size:{}",list.size());
}

private static void update(int i){
    list.add(i);
}

}

但是这段代码在运行的时候却偶尔会抛出异常:
图片描述
当然,有时候也会运行出正确的结果来,想请教一下老师这里为什么数组下标会越界,ArrayList在扩容时还有什么讲究吗?

写回答

1回答

Jimin

2019-08-14

你好,本质上就是多个线程都会过来修改,因为没做同步处理,不同线程操作时出现线程不安全,也证实了这个类是线程不安全类。你遇到的问题属于一个比较经典的问题,你看一下这篇文章的演示吧,https://www.cnblogs.com/smellpawn/p/10841480.html

0
3
Jimin
回复
qq_超人不会飞_22
嗯,基本上是正确的,多线程下执行i++都会有问题
2019-08-15
共3条回复

Java高并发编程,构建并发知识体系,提升面试成功率

构建完整并发与高并发知识体系,倍增高薪面试成功率!

3923 学习 · 832 问题

查看课程