ArrayList的线程不安全问题

前面我们学了ArrayList和LinkedList,回顾学习地址:
http://blog.csdn.net/github_26672553/article/details/75006230

Thread类

该类继承接口Runnable,启动一个线程代码案列。

Thread t = new Thread();
t.start();//这个方法是代表启动一个线程

只不过上面代码就这样写 没有什么意义。

new Thread()的时候需要传入参数(一个继承Runnable类的对象,或者匿名内部类)。

如果业务稍微复制推荐自定义一个继承Runnable的类。
比如MyThread.java


public class MyThread implements Runnable {

    @Override
    public void run() {
            System.out.println("hello");
    }
}

我们在入口函数中演示开启5个线程:

    public static  void main(String[] args) throws InterruptedException{
        for (int i=1;i<=5;i++){
            Thread thread = new Thread(new MyThread());
            thread.start();
        }
    }

运行程序会输出 5个abc

这就是Java的多线程

ArrayList的线程不安全

1、改造一下MyThread.java文件代码:

import java.util.List;

public class MyThread implements Runnable {

    private List<String>list;

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

    @Override
    public void run() {
          for (int i=1;i<=50;i++){
              this.list.add("hi");
          }
    }
}

添加一个List类型的属性,在类构造函数中要求参数传入并保存。run()方法添加50个hi字符串。

2、程序入口文件

    public static  void main(String[] args) throws InterruptedException{

        List<String> list = new ArrayList<String>();


        for (int i=1;i<=5;i++){
            Thread thread = new Thread(new MyThread(list));
            thread.setName("t-"+String.valueOf(i)); //给线程起个名字
            thread.start();
        }

        //主线程
        System.out.println(list.size()); //多次运行程序 发现打印的值不一样
    }

给5个子线程 都传入list对象了,最后在主线程输出list的大小,但多次运行程序发现值有变化,有时是250有时是200

这个情况就是ArrayList的线程不安全

List<String> list = new Vector<String>();

换成Vector后每次运行结果都是一样,说明Vector是线程安全的。

但也不是绝对的,如果子线程执行时间太长,主线程就执行了呢?
意思是:如果子线程还在往list里添加数据,比如循环10000次,这个时候可能后面主线程就已经开始执行了。

要解决主线程必须在子线程执行完毕之后 才执行

简单的解决方法:Thread.join
线程B中调用了线程A的Join()方法,知道线程A执行完毕后,才会继续执行线程B。

    public static  void main(String[] args) throws InterruptedException{

        // 用来装 线程 的对象
        List<Thread> threadList = new ArrayList<Thread>();

        // list对象
        List<String> list = new Vector<String>();

        for (int i=1;i<=5;i++){
            Thread thread = new Thread(new MyThread(list));
            thread.setName("t-"+String.valueOf(i)); //给线程起个名字
            thread.start();

            threadList.add(thread); //把子线程装进去
        }

        for (Thread thread:threadList){
            thread.join();
        }


        //主线程
        System.out.println(list.size()); //多次运行程序 发现打印的值不一样
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值