JUC- 集合类安全

5- 集合类安全

5.1 List集合

5.1.1 单线程

package cn.guardwhy.List01;

import java.util.Arrays;
import java.util.List;

/*
单线程安全
*/
public class ListTest01 {
    
    
    public static void main(String[] args) {
    
    
        List<String> list = Arrays.asList("kobe", "curry", "james");
        list.forEach(System.out::println);
    }
}

5.1.2 多线程

package cn.guardwhy.List01;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/*
并发修改异常:java.util.ConcurrentModificationException
*/
public class ListTest02 {
    
    
    public static void main(String[] args) {
    
    
        // 1.创建list集合
        List<String> list = new ArrayList<>();
        // 2.多线程
        for (int i = 0; i <= 100; i++) {
    
    
            new Thread(()->{
    
    
                list.add(UUID.randomUUID().toString().substring(0,10));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

执行结果

5.1.3 解决线程不安全

CopyOnWriteArrayList

代码示例

package cn.guardwhy.List01;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/*
并发下Arraylist是不安全的
*/
public class ListTest03 {
    
    
    public static void main(String[] args) {
    
    
        /*
        * 解决方案:
        * 1. List<String> list = new Vector<>();
        * 2. List<String> list = Collections.synchronizedList(new ArrayList<>());
        * 3. List<String> list = new CopyOnWriteArrayList<>();
        */

        // 1.创建list集合
        // CopyOnWrite 写入时复制
        List<String> list = new CopyOnWriteArrayList<>();
        // 2.多线程
        for (int i = 0; i <= 100; i++) {
    
    
            new Thread(()->{
    
    
                list.add(UUID.randomUUID().toString().substring(0,10));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

写入时复制(CopyOnWrite)思想

写入时复制(简称COW)思想是计算机程序设计领域中的一种优化策略。此做法主要的优点是如果调用者没有修改资源,就不会有副本private copy)被创建,因此多个调用者只是读取操作时可以共享同一份资源。读写分离,写时复制出一个新的数组,完成插入、修改或者移除操作后将新数组赋值给array。

CopyOnWriteArrayList性能比Vector好

Vector是增删改查方法都加了synchronized,保证同步,但是每个方法执行的时候都要去获得锁,性能就会大大下降,而CopyOnWriteArrayList 只是在增删改上加锁,但是读不加锁,在读方面的性能就好于Vector,CopyOnWriteArrayList支持读多写少的并发情况。

5.2 Set集合

5.2.1 多线程

package cn.guardwhy.List01;

import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
// java.util.ConcurrentModificationException
public class SetTest01 {
    
    
    public static void main(String[] args) {
    
    
        // 1.创建Set集合
        Set<String> set = new HashSet<>();
        // 2.多线程
        for (int i = 0; i <= 100; i++) {
    
    
            new Thread(()->{
    
    
                set.add(UUID.randomUUID().toString().substring(0,10));
                System.out.println(set);
            },String.valueOf(i)).start();
        }
    }
}

5.2.2 解决线程不安全

CopyOnWriteArraySet

代码示例

package cn.guardwhy.List01;

import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;

public class SetTest01 {
    
    
    public static void main(String[] args) {
    
    
        /*
         解决方案:
         1. Set<String> set = Collections.synchronizedSet(new HashSet<>());
         2. Set<String> set = new CopyOnWriteArraySet<>();
         */

        // 1.创建Set集合
        Set<String> set = new CopyOnWriteArraySet<>();
        // 2.多线程
        for (int i = 0; i <= 100; i++) {
    
    
            new Thread(()->{
    
    
                set.add(UUID.randomUUID().toString().substring(0,10));
                System.out.println(set);
            },String.valueOf(i)).start();
        }
    }
}

hashset底层就是hashMap

add方法 就是map的put方法

5.3 Map集合

5.3.1 源码分析

hashMap底层是数组+链表+红黑树

Map<String,String> map = new HashMap<>();
// 等价于
Map<String,String> map = new HashMap<>(16,0.75);

5.3.2 多线程

package cn.guardwhy.List01;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/*
并发修改异常:java.util.ConcurrentModificationException
*/
public class MapTest01 {
    
    
    public static void main(String[] args) {
    
    
        // 1.创建Map集合对象
      Map<String, String> map = new HashMap<>();
        // 2.多线程
        for (int i = 0; i <= 30; i++) {
    
    
            new Thread(()->{
    
    
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
                System.out.println(map);
            },String.valueOf(i)).start();
        }
    }
}

执行结果

5.3.2 解决线程不安全

ConcurrentHashMap

代码示例

package cn.guardwhy.List01;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/*
并发修改异常:java.util.ConcurrentModificationException
*/
public class MapTest01 {
    
    
    public static void main(String[] args) {
    
    
       Map<String, String> map = new ConcurrentHashMap<>();
        // 2.多线程
        for (int i = 0; i <= 30; i++) {
    
    
            new Thread(()->{
    
    
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
                System.out.println(map);
            },String.valueOf(i)).start();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/hxy1625309592/article/details/113974109