测试各种变量是否是线程安全的

目录

先说结论

成员变量

1.成员变量---int类型的成员变量number                   线程共享,会有并发

2.成员变量---string类型                                     线程共享,会有并发

3.成员变量---int /string类型的数组                                           线程共享,会有并发

4.成员变量---ArrayList                             线程共享,会有并发

5.成员变量---HashMap                 线程共享,会有并发

局部变量

1.局部变量-- int类型                              线程不共享,不会有并发

2.局部变量---string类型                           线程不共享,不存在并发

3.局部变量--  int类型的数组                         线程不共享,不存在并发

4.局部变量---ArrayList                   线程不共享,不存在并发

5.局部变量---HashMap        线程不共享,不存在并发


先说结论

作为成员变量,线程共享存在并发的有

1.int类型

2.string类型

3.int[] /string[]数组

4.ArrayList 集合

5.HashMap map

作为局部变量,线程不共享没有并发的有

1.int类型

2.string类型

3.int[] /string[]数组

4.ArrayList 集合

5.HashMap map

前提条件,把这个类设成是单例模式,也就是说,这个类只能创建一个对象,然后多个线程在一个对象中去争抢资源.

成员变量

1.成员变量---int类型的成员变量number                   线程共享,会有并发

public class Stu {
    private int number;
    private String age;
    private String math;
    private int[]  shuzu= {1,2,3} ;
    public  void aa(){
        number++;
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(number);
    }
@Component
public class MyRunnable implements Runnable{
    @Override
    public void run(){
        //创建出stu的单例对象
        Stu stu = Stu.getInstance();
        stu.aa();
        //把stu对象的地址打印出来
        System.out.println(Thread.currentThread().getName()+"  嘿嘿  "+System.identityHashCode(stu));
    }
}
public class testb {
    public static void main(String[] args) {
        //创建线程池
        ExecutorService pool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            pool.submit(new MyRunnable());
        }
        pool.shutdown();
    }
}

 创建10个线程去执行stu对象的成员变量的number++;

下图是结果:

 测试各种变量是否是线程安全的_第1张图片

打印的int类型的成员变量的内存地址都一样.这是为什么?

 打印的结果混乱,证明多线程争抢,发生了并发.

2.成员变量---string类型                                     线程共享,会有并发

测试各种变量是否是线程安全的_第2张图片

创建10个线程去获得单例对象stu内的成员变量string name,   让10个线程都去改变string name的值,然后打印最后string name的值,和每个线程执行到的string name的内存

测试各种变量是否是线程安全的_第3张图片

 结果显示,10个线程去改变值后的string name的内存是值相同的内存一样,值不相同的内存不一样.

结果是混乱的,证明有并发的现象出现,就是发生了并发.

3.成员变量---int /string类型的数组                                           线程共享,会有并发

测试各种变量是否是线程安全的_第4张图片

测试各种变量是否是线程安全的_第5张图片

 创建10个线程去获得单例对象stu内的成员变量int[] shuzu,   让10个线程都去对数组减一操作,然后打印最后数组的元素的值,和每个线程执行到的数组的内存

下面是结果:

测试各种变量是否是线程安全的_第6张图片

 结果显示,10个线程创建的数组的内存都是一样的,证明这个成员变量的数组是线程共享的,一个线程new出来一个数组后,那么其他数组就共享使用这个数组了.

而每个线程都去减一后,打印的结果很乱有重复,证明有并发的现象出现,就是发生了并发.

4.成员变量---ArrayList                             线程共享,会有并发

测试各种变量是否是线程安全的_第7张图片

 创建10个线程去获得单例对象stu内的成员变量ArrayList ,   让10个线程都去对集合添加一个1元素,然后打印最后集合的值,和每个线程执行到的集合的内存

下面是结果:

 测试各种变量是否是线程安全的_第8张图片

 结果显示,10个线程创建的ArrayList集合的内存都是一样的,证明这个成员变量的集合是线程共享的,一个线程new出来一个集合后,那么其他数组就共享使用这个集合了.

而每个线程都去对集合添加1元素后,打印的结果有null出现,证明有并发的现象出现,就是发生了并发.

5.成员变量---HashMap                 线程共享,会有并发

测试各种变量是否是线程安全的_第9张图片

 创建10个线程去获得单例对象stu内的成员变量hashmap ,   让10个线程都去对hashmap添加一个键值对,然后打印最后hashmap的值,和每个线程执行到的hashmap的内存

下面是结果:

测试各种变量是否是线程安全的_第10张图片

 结果显示,10个线程创建的hashmap的内存都是一样的,证明这个成员变量的hashmap是线程共享的,一个线程new出来一个hashmap后,那么其他线程就共享使用这个hashmap了.

而每个线程都去对集合hashmap添加一个键值对,打印的结果最后是第3个线程的,证明有并发的现象出现,就是发生了并发.

局部变量

1.局部变量-- int类型                              线程不共享,不会有并发

测试各种变量是否是线程安全的_第11张图片

  创建10个线程去执行stu对象的aa()方法里的局部变量的number++;

下图是结果: 

测试各种变量是否是线程安全的_第12张图片

 内存地址都是一样的?

结果都是1.证明不存在并发

2.局部变量---string类型                           线程不共享,不存在并发

测试各种变量是否是线程安全的_第13张图片

 创建10个线程去执行stu对象的aa()方法里的string name +"啊";

 测试各种变量是否是线程安全的_第14张图片

 结果内存都不一样,证明局部变量sting类型线程不共享.

结果值都是一样的,证明线程没有发生争抢.

3.局部变量--  int类型的数组                         线程不共享,不存在并发

测试各种变量是否是线程安全的_第15张图片

 创建10个线程去执行单例对象stu的aa()方法,   让这10个数组都去对这个数组减一操作,然后打印最后数组的元素的值,和每个线程执行到的数组的内存

下图是结果

测试各种变量是否是线程安全的_第16张图片

结果证实:每个线程new出的数组的内存地址都不一样... (int [] arr=new int[]{0})这种在成员方法里的局部变量,  每个线程都会自己去new一个数组出来, 会在堆中new出10个地址不同的数组来,然后每个线程执行的时候各找各的new出的数组,所以它们互不影响.

结果证实:每个线程都new了一个自己的数组,因此它们各自减一,得的结果都是9,不存在并发.

所以,  数组作为局部变量,是线程不共享的,是线程安全的.

4.局部变量---ArrayList                   线程不共享,不存在并发

                   测试各种变量是否是线程安全的_第17张图片

 创建10个线程去new局部变量ArrayList ,   让10个线程都去对集合添加一个1元素,然后打印最后集合的值,和每个线程执行到的集合的内存

下面是结果:

测试各种变量是否是线程安全的_第18张图片       

 结果显示,10个线程创建的ArrayList集合的内存是不一样的,证明这个局部变量的集合是线程私有的.

而每个线程都去对集合添加1元素后,打印的结果都为1,证明不存在并发.

5.局部变量---HashMap        线程不共享,不存在并发

测试各种变量是否是线程安全的_第19张图片

 创建10个线程去new局部变量hashmap ,   让10个线程都去对hashmap添加一个键值对,然后打印最后hashmap的值,和每个线程执行到的hashmap的内存

下面是结果:

 测试各种变量是否是线程安全的_第20张图片

 结果显示,10个线程创建的hashmap的内存是不一样的,证明这个局部变量的hashmap是线程私有的.

而每个线程都去对hashmap添加一个键值对后,打印的结果互不影响,证明不存在并发.

你可能感兴趣的:(java基础,java,开发语言)