Java~源码分析为什么ArrayList是线程不安全的, 如何将其变为线程安全的

   日期:2020-09-28     浏览:100    评论:0    
核心提示:文章目录ArrayList不是线程安全的,使用一个案例演示结果分析需要线程安全怎么办?源码分析其为何安全?ArrayList不是线程安全的,使用一个案例演示任务类import java.util.List;/** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-09-27 * Time: 15:42

文章目录

    • ArrayList不是线程安全的,使用一个案例演示
      • 结果分析
    • 需要线程安全怎么办?
      • 源码分析其为何安全?

ArrayList不是线程安全的,使用一个案例演示

  • 任务类
import java.util.List;


//线程任务类
public class CollectionTask implements Runnable { 

    private List<String> list;

    public CollectionTask(List<String> list) { 
        this.list = list;
    }


    @Override
    public void run() { 
        //在任务中插入名字
        try { 
            Thread.sleep(100);
        } catch (InterruptedException e) { 
            e.printStackTrace();
        }
        list.add(Thread.currentThread().getName());

    }
}

  • 测试类
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


//测试类
public class ArrayListSafetyTest { 

    public static void main(String[] args) { 
        List<String> list = new ArrayList<>();
        //list = Collections.synchronizedList(list);
        CollectionTask task = new CollectionTask(list);
        for (int i = 0; i < 50; i++) { 
            new Thread(task).start();
        }
        //等待线程执行
        try { 
            Thread.sleep(1000);
        } catch (InterruptedException e) { 
            e.printStackTrace();
        }
        //遍历链表
        for (String str : list
             ) { 
            System.out.println(str);
        }


    }
}

结果分析

  • 问题就是遍历链表出现null值, 我们看看源码分析一下这是为什么
public boolean add(E e) { 
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //添加一次元素就会size++一次
        elementData[size++] = e;
        return true;
    }
  • 问题就出在size++上, 多个线程同时给一个位置添加元素, 导致size++了, 但是数据覆盖了, 所以就会出现空的位置

需要线程安全怎么办?

  • 使用Collections.synchronizedList(list)或者Vector<>()
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


//测试类
public class ArrayListSafetyTest { 

    public static void main(String[] args) { 
        List<String> list = new ArrayList<>();
        //重点
        list = Collections.synchronizedList(list);
        CollectionTask task = new CollectionTask(list);
        for (int i = 0; i < 50; i++) { 
            new Thread(task).start();
        }
        //等待线程执行
        try { 
            Thread.sleep(1000);
        } catch (InterruptedException e) { 
            e.printStackTrace();
        }
        //遍历链表
        for (String str : list
             ) { 
            System.out.println(str);
        }


    }
}

源码分析其为何安全?

  • 很简单就是给加个一把锁
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服