list.size()阻塞踩坑

在多线程环境中,即使使用线程安全的List,如Collections.synchronizedList,调用size()方法仍可能出现阻塞,因为其他线程可能在插入元素。当size()需要遍历整个list时,如果list正在被修改,会阻塞直到获取锁。通过在添加元素后加入短暂睡眠,可以避免这种现象。线程安全的实现应考虑快速失败机制,以防止阻塞带来的性能影响。
摘要由CSDN通过智能技术生成

今天导师在群里问下面这段代码,list也改了线程安全的List,循环一万次往list里塞元素,为什么看size都是小于一万的,而且每次的值都是不一样的?
在这里插入图片描述
仔细看了代码,确实也感觉奇怪。明明已经用了线程安全的list,应该不存在线程冲突的问题啊。但看这不确定的结果,又是线程不安全的表现。

最后,组内的大佬说,可能是list.size()的问题,list.size()查看大小的时候也是阻塞的,可能别的线程还在插入,list.size()查看的时候把list阻塞了。可以试试sleep一段时间后再list.size(),看还会不会出现这种现象。

试了下,果然不再出现了。强啊

补个chatGPT的解释:
在这里插入图片描述

线程安全list 的size()会导致阻塞吗
在某些情况下,线程安全的list的size()可能会导致阻塞。这取决于具体的实现方式
对于某些实现,size()是非常快速的,可以立即返回list的大小,而不会阻塞任何线程。这通常是通过维护一个计数器或计算list的大小来实现的。因此,如果您使用这样的实现,调用size()方法不会阻塞
然而,对于另一些实现,size()可能需要遍历整个list,以便计算大小。在这种情况下,当调用size()方法时,如果其他线程正在修改list,可能会发生阻塞。因为在遍历list时,会获取个锁来保证遍历的原子性,如果其他线程正在修改list,则size()方法需要等待该锁被释放才能继续执行,这可能导致阻塞
因此,具体取决于使用的线程安全list的实现方式。建议使用实现了“快速失败”机制的list,即在多线程环境下,如果list在遍历时被修改,会立即抛出ConcurrentModificationException异常,以避免因为阻塞导致的性能问题。

代码:

package main.java.threadpool ;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;import java.util.Random;

public class ThreadTest {

    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        List<Integer> list = Collections.synchronizedList(new ArrayList<>());

        for (int i = 0; i < 100000; i++) {
            Thread t = new Thread() {
                @Override
                public void run() {
                    list.add(new Random().nextInt());
                }
            };
            t.start();
            System.out.println("time:" + (System.currentTimeMillis() - start));
            System.out.println("size:" + list.size());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值