1.背景

package com.ydlclass.collection;

import com.ydlclass.lock.ThreadUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class DataModFault {
    public static void main(String[] args) throws InterruptedException {
        final List<Integer> list = new ArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(200);
        for (int i = 0; i < 200; i++) {
            new Thread(() ->{
                ThreadUtil.sleep(10);
                list.add(1);
                countDownLatch.countDown();
            }).start();
        }

        countDownLatch.await();
        System.out.println(list.size());//最后的结果只有195,有时可能还会抛出数组越界异常(多线程情况的问题出现的问题可能比较多)

    }
}

2.set,hashMap等类都是线程不安全的,但是有对应的线程安全的类;其中,对于list使用Vector实现线程安全,hashMap使用hashTable类实现线程安全;

3.例如vector这个类的大部分方法都是用synchronized关键字修饰,实现线程安全的;Vector父类是List。(线程安全的)

package com.ydlclass.collection;

import com.ydlclass.lock.ThreadUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;

public class DataModFault {
    public static void main(String[] args) throws InterruptedException {
        final List<Integer> list = new Vector<>();
        CountDownLatch countDownLatch = new CountDownLatch(200);
        for (int i = 0; i < 200; i++) {
            new Thread(() ->{
                ThreadUtil.sleep(10);
                list.add(1);
                countDownLatch.countDown();
            }).start();
        }

        countDownLatch.await();
        System.out.println(list.size());//最后的结果为200

    }
}

4.hashTable类:他的使用方式和实现多线程安全的方式与vector相似,

package com.ydlclass.collection;

import com.ydlclass.lock.ThreadUtil;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;

public class DataModFault {
    public static void main(String[] args) throws InterruptedException {
        Hashtable<Integer, Integer> list= new Hashtable<>();//基本数据类型不能作为泛型的原因还有就是基本数据类型不能实现comparable接口
        // ,那么对于集合操作就有问题了
        CountDownLatch countDownLatch = new CountDownLatch(200);
        for (int i = 0; i < 200; i++) {
            int finalI = i;
            new Thread(() ->{
                ThreadUtil.sleep(10);
                list.put(finalI, finalI);
                countDownLatch.countDown();
            }).start();
        }

        countDownLatch.await();
        System.out.println(list.size());//最后的结果为200

    }
}
//最后的结果为200