Java--JUC--集合的线程安全问题

  1. 标准的接口:超过一个方法的定义
  2. 函数是接口:有且仅有一个方法的定义,可以使用@FunctionalInterface,可以自己加上,自己不加在内部也会自动位我们加上这个注解
  3. lambda表达式形式:拷贝小括号(接口中方法的小括号和里面的参数),写死右箭头,落地大
  4. 在函数式接口中:
    1. default 修饰的方法可以有多个,(此方法的具体的实现)
    2. static类型的方法也可以有多个
    3. 函数是接口的调用方式:
      1. public static void main(String[] args) {
                //   普通形式
                Foo foo=new Foo() {
                    @Override
                    public void sayHello() {
                        System.out.println("sayHello****");
                    }
                };
        
        //        lambda形式的调用
                Foo foo1=()->{
                    System.out.println("sayHello****");
                };
                foo.sayHello();
                foo1.sayHello();
            }
    4.  函数是接口的定义: 
      1. //标准接口:接口中超过一个方法
        //函数式接口:当借口中有且仅有一个方法时,才会使用@FunctionalInterface,可以自己加上,自己不加在内部也会自动位我们加上这个注解
        @FunctionalInterface
        interface Foo{
        
        //    接口有且仅有一个方法
            public void sayHello();
        //    public int add(int x,int y);
            default void sayHello(int x,int y){
                System.out.println(x+y);
            }
            default void sayHello1(int x,int y){
                System.out.println(x+y);
            }
            public static int dey(){
                return 0;
            }
            public static int dey1(){
                return 0;
            }
        }
    5. 线程的实现的接口Runnable接口是函数是接口可以使用lambda表达式的形式的调用
      1. new Thread(() ->{ for (int i=1;i<=40;i++) { ticket.sale(); } },"A").start();
                new Thread(() ->{ for (int i=1;i<=40;i++) { ticket.sale(); } },"B").start();
                new Thread(() ->{ for (int i=1;i<=40;i++) { ticket.sale(); } },"C").start();
    6. arraylist创建时的初始值时10,hasmap创建时的初始值时16,第一次扩容扩容到15,拷贝(搬家)的方式:arraylist.copyof()。第二次扩容22,线程不安全
  5. 解决arraylist线程安全的三种方式:
    1. List list=new Vector(); 
    2. List list= Collections.synchronizedList(new ArrayList<>());
    3. List<String> list=new CopyOnWriteArrayList<>()
  6. 写时复制(List<String> list=new CopyOnWriteArrayList<>())
    1. CopyOnWrite容器即写时复制的容器。往一 - 个容器添加元素的时候,不直接往当前容器object[]添加,而是先将当前容器object[ ]进行copy,
    2. 复制出- -个新的容器0bject[] newElements, 然后新的容器0bject[] newElements 里添加元素,添加完元素之后,
    3. 再将原容器的引用指向新的容器setArray(newElements);. 这样做的好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一-种读 写分离的思想,读和写不同的容器

    4. public boolean add(E e) 
      final ReentrantLock Lock = this. lock;
      Lock. lock();
      try
      object[] elements = getArray(); .
      int len = elements. length;
      object[] newElements = Arrays . copyof(elements, len + 1);
      newELements[len] = e;
      setArray(newELements);
      return true;
      finally{
      lock. unlock();
      }
       
  7. 解决hashSet线程安全问题:
    1. hashSet是线程不安全的,他的底层是HashMap,
    2. HashMap是key -v键值对,但是HashSet是一个值,是如何实现HashSet的呢?key是我们向set传入的值,但是Value是一个Present  Object类型的常量,所有我们只用传入key就可以不用传入value
    3. Set<String> set=new CopyOnWriteArraySet<>();
  8. 解决HashMap的线程安全问题
    1. Map<String,Object> map=new ConcurrentHashMap<>();
  9. 解决线程安全的具体代码
    1. public void mapNotSafe(){
      //        Map<String,Object> map=new HashMap();
      //        解决Map线程安全的问题
              Map<String,Object> map=new ConcurrentHashMap<>();
              for (int i=0;i<30;i++){
                  new Thread(() ->{
                      map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));
                      System.out.println(map);
                  },String.valueOf(i)).start();
      
              }
      
          }
          public void setNotSafe() {
      //        Set<String > set =new  HashSet<>();
      //        解决set线程安全问题,读写分离的原理,读写使用不同的容器
              Set<String> set=new CopyOnWriteArraySet<>();
              for (int i = 0; i < 30; i++) {
                  new Thread(() -> {
                      set.add(UUID.randomUUID().toString().substring(0, 8));
      //                set.forEach(System.out::println);
                      System.out.println(set);
                  }, String.valueOf(i)).start();
              }
      
      
          }
      
          public void listNotSafe() {
      //        List list=new ArrayList();
      //        List list=new Vector();
      //        List list= Collections.synchronizedList(new ArrayList<>());
              List<String> list = new CopyOnWriteArrayList<>();//写时复制,读写分离的原理
      //        写的时候会复制一份,然后在新的容器中写,不会影响其他人的读
              for (int i = 0; i < 30; i++) {
                  new Thread(() -> {
                      list.add(UUID.randomUUID().toString().substring(0, 8));
                      System.out.println(list);
      //                list.forEach(System.out::println);
                  }, String.valueOf(i)).start();
              }
          }
  10.  

      
posted @ 2021-06-04 11:07  张紫韩  阅读(103)  评论(0编辑  收藏  举报