关于Arraylist集合线程不安全问题的解决和测试过程出现的问题

关于Arraylist集合线程不安全问题的解决和测试过程出现的问题

解决线程不安全问题

import java.util.ArrayList;

/**
 * @Auther Oonday
 * @Date 2021-01-22 15:35
 */

public class unsafelist  {
    public static void main(String[] args) throws InterruptedException {
        ArrayList list = new ArrayList();
        for (int i = 0; i <= 1000; i++) {
            new Thread(()->{
               synchronized (list){
                   list.add(Thread.currentThread().getName());
               }
            }).start();


        }
//这样就解决了Arrylist不安全问题,那么原来是什么呢?还有测试过程出现的问题

    }
}

解决Arraylist不安全问题的原理

1.使用的方法:使用同步代码块来解决线程不安全的问题,这这里最难的就是如何选择那个对象作为同步代码块所需要的锁,我们只要选择需要被多个线程增删改的对象作为锁,这里我们时list集合。
2.出现不安全的原因:上面的代码是 ,所有的线程都要去往list里面添加内容,如果此时,好几个线程都访问list的同一个位置,那么这时候就会导致前一个添加到此位置的内容被覆盖,所以在输出list的大小时i,会出现不是1001个,而是小于这个数。我们知道,线程的执行是靠cpu来调度的,所以并不是等到该线程执行完才会继续执行其他,有可能刚好要执行该位置时,另外一条线程夺得cpu使用权,以知道添加这个位置,然后两个就接连添加到这个地方,所以会存在上面那种同时访问一个位置的情况。
3.解决的原理:同步代码块是一种锁机制,传递一个对象给它,这个对象是所有需要访问到的线程公用的对象,当一个线程获取到此对象的锁并锁住,其他线程执行到这里时,发现,对象被锁住了,所以只能挂起状态(阻塞状态),等待该线程执行完同步内容,然后该线程释放锁,其他对象才一起争夺锁的使用权。这样就实现安全的线程。

测试过程中出现的问题

//        System.out.println(list.size());

直接在主线程中输出这个list的大小,发现并没有解决同步问题,其实并不是没有解决,而是,线程安全问题已经解决了,但是,由于主线程获取到执行权,然后提前输出了结果,导致大小并不是应该有的大小。

Thread.sleep(1000);

让主线程睡眠一会,这样,就能让结果正确显示为1001.延长主线程结束的时间。
为了进一步验证,在主线程后面添加上一下代码测试。

//        for (int i = 0; i < 1000; i++) {
//            System.out.println(list.size()+"->"+list.get(i+1));
//        }

发现输出真的时1001个的线程名字,证明我们的同步确实时解决了的。
注;文章同步到公众号:我也是一名新手,有兴趣的小伙伴可以来一起学习哦,加油!
公众号

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值