JUC编程—集合不安全与Callable接口

1、集合类不安全

11、LIst不安全

package com.zkw.JUC并发编程.unsafe;

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

//java.util.ConcurrentModificationException 并发修改异常

public class ListTest {
    public static void main(String[] args) {
        /**
         * 并发下的 ArrayList 是不安全的
         * list jdk1.2出来的
         * 解决方案:
         *1、List<String> list = new Vector<>();jdk1.0出来的 不建议使用
         *2、List<String> list = Collections.synchronizedList(new ArrayList<String>());
         *3、List<String> list = new CopyOnWriteArrayList<>();
         */
        /**
         * CopyWrite 写入时复制  简称COW 计算机程序设计领域的一种优化策略
         * 多线程调用的时候,list,读取的时候,固定的,写入(覆盖)
         * 在写入的时候避免覆盖,造成数据问题
         * 读写分离
         * CopyOnWriteArrayList VS Vector 优势在哪里?
         * CopyOnWriteArrayList用的是Lock锁,而Vector用的是synchronized锁,前者效率比后者高
         * 因为synchronized修饰的是同步方法,每一个线程多要去等锁,同一时刻只有一个线程在执行
         */
       List<String> list = new CopyOnWriteArrayList<>();

        for (int i = 1; i <= 100; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

1.2、Set不安全

package com.zkw.JUC并发编程.unsafe;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 同理 java.util.ConcurrentModificationException 并发修改异常
 */
public class SetTest {
    
    
    public static void main(String[] args) {
    
    
        //Set<String> set = new HashSet<String>();不安全
        /**
         * 解决方案:
         * 1、借助工具类Collections 把它转为安全的
         * Set<String> set = Collections.synchronizedSet(new HashSet<String>());
         * 2、使用CopyWriteArraySet
         * Set<String> set = new CopyOnWriteArraySet<String>();
         */
        Set<String> set = new CopyOnWriteArraySet<String>();
        for (int i = 1; i <= 1000; i++) {
    
    
            new Thread(()->{
    
    
                set.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(set);
            },String.valueOf(i)).start();
        }
    }
}

hashSet 底层是什么?

 public HashSet() {
    
    
        map = new HashMap<>();
    }
// add set 本质就是 map key是无法重复的
 public boolean add(E e) {
    
    
        return map.put(e, PRESENT)==null;
    }

    private static final Object PRESENT = new Object();//不变的值

1.3、Map不安全

HashMap基本的操作

在这里插入图片描述

package com.zkw.JUC并发编程.unsafe;

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

// java.util.ConcurrentModificationException 并发修改异常
public class MapTest {
    
    
    public static void main(String[] args) {
    
    
        // 默认等价于什么?new HashMap<>(16,0.75);
        // Map<String, String> map = new HashMap<>();
        /**
         * 解决方案:
         * 1、Map<String, String> map = new ConcurrentHashMap<String, String>();
         * 2、Map<String, String> map = Collections.synchronizedMap(new HashMap<String,String>());
         */
        Map<String, String> map = new ConcurrentHashMap<String, String>();

        for (int i = 1; i <= 100; i++) {
    
    
            new Thread(()->{
    
    
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
                System.out.println(map);
            }).start();
        }
    }
}

7、Callable

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

package com.zkw.JUC并发编程.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableTest {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        //new Thread(new Runnable()).start();
        //new Thread(new FutureTask<V>()).start();
        //new Thread(new FutureTask<V>(Callable )).start();

        MyThread thread = new MyThread();
        FutureTask futureTask = new FutureTask(thread);// 适配类

        new Thread(futureTask,"A").start();
        new Thread(futureTask,"B").start();// 结果会被缓存,效率高

        Integer o = (Integer)futureTask.get();//这个get 方法可能会产生阻塞!可以把它放在最后边
        //或者使用异步通信来处理
        System.out.println(o);
    }
}
class MyThread implements Callable<Integer>{
    
    
    @Override
    public Integer call() {
    
    

        System.out.println(Thread.currentThread().getName()+"=>Call()");
        return 1024;
    }
}

细节:1、会缓存;2、结果可能需要等待,会阻塞

Guess you like

Origin blog.csdn.net/fgets__/article/details/120781574