zoukankan      html  css  js  c++  java
  • 集合类不安全

    JUC (java.util.concurrent)
    1.1 进程/线程

    1.2 并发和并行有什么区别?

    并发就像是秒杀一样,多个线程去访问同一个资源。并行各种事情一路并行去做

    JUC的三个包

    java.util.concurrent
    java.util.concurrent.atomic(原子性)
    java.util.concurrent.locks(锁)

    3个售票员 卖出30张票

    1.高内聚 ,低耦合的前提下 线程 操作 资源类

      1.1 一言不合,先创建一个资源类
    
    class Ticket{     //资源类 = 实例变量 +  实例方法
          private int number = 30;
          Lock lock = new ReentrantLock();
          public void sale(){
                lock.lock();
                try{
                      if(number>0){
                            sout(Thread.currentThread().getName());
                      }
    
                }catch(Exception e){
                      e.printStackTrace
                }finally{
                      lock.unlock();
                }
          
          }
    
    
    }
    

    main{ //主线程,一切线程的入口

    Ticket ticket = new ticket();

    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;

    /************

    new Thread({
          @Override
          public void run(){
                for(int i = 1; i<=40;i++){
                      ticket.sale();
                }
          }
    
    },"AA").start();
    new Thread({
          @Override
          public void run(){
                for(int i = 1; i<=40;i++){
                      ticket.sale();
                }
          }
    
    },"BB").start();
    new Thread({
          @Override
          public void run(){
                for(int i = 1; i<=40;i++){
                      ticket.sale();
                }
          }
    
    },"cc").start();
    
    //Thread t1 = new Thread();
    //Thread t2 = new Thread();
    //Thread t3 = new Thread();
    
    }
    

    synchronize 重锁

    Lock ReentrantLock 可重入锁/递归锁

    java获得多线程有四种方法:

    1.继承Thread类
    2.实现Runnable接口
    3.实现Callable接口通过FutureTask包装器来创建Thread线程
    4.通过线程池

    线程的启动不是以start()为转移,而是等待底层操作系统和CPU的调度
    start就是一个就绪,发生了线程调度才会执行

    多线程有几种状态 (6)

    new
    Runnable(就绪)
    Blocked(阻塞)
    WAITING(等待)

    waiting和wait不是一回事,waiting是一个状态,wait是一个方法

    TIMED_WAITING()

    Timed_waiting 和 waiting的区别 time_waiting是过时不候,waiting是一直等

    Terminated()

    接口是特殊的类,类就可以new

    new一个接口 叫做匿名内部类 然后 new一个类 ,多肽

    函数式编程 lambda表达式 单方法的匿名内部类 @FuncationalInterface

    拷贝小括号,写死右箭头,落地大括号

    default(定义 + 实现)

    综上

    new Thread(()->{for(i=0;i<=40;i++)ticket.sale();},"名字").start

    new ArrayList 底层是new什么

    new 一个数组

    数组都有类型,Arraylist 底层是什么类型

    Object

    默认容量是多少

    java7 是 10
    java8 是空引用,当第一次调用add扩容到10. hashmap默认是16

    java8 new 一个 arraylist底层是new一个初始值为10的数组

    怎么扩容的 10 - 15 - 22 - 33

    第一次扩容 是原值的一半 拷贝方法 Arrays.copyOf()

    第二次扩容 原值的一般

    而hashmap 扩容是原值的一倍 ,向右移一位

    ArrayList 是否线程安全

    例: 1.故障现象
    java.util.ConcurrentModificationException(业务还没实现完了,就被另一个线程打断)
    2.导致原因
    多线程 并发争抢同一个资源类且没加锁
    3.解决方法
    3.1 加锁? new Vector<>();add没有锁,又不可能给arraylist的add加锁,这是需要用到同List中的线程安全vector中的add去进行操作

            3.2 Collections.synchronizedList(new Arraylist<>())
    
            3.3 new CopyOnWriteArrayList()
    
    
      4.优化建议
            new CopyOnWriteArrayList();
    

    List list = new ArrayList<>();
    list.add("a");
    list.add("a");
    list.add("a");
    list.forEach(system.out::println)

    就一个线程 ,安全

    当多个线程时暴露线程不安全

    List<string> list = new ArrayList<>();
    List<string> list = new vector<>();  // 如果不能使用vector 呢
    List<string> list = Collections.synchronizedList(new Arraylist<>()); //用collections  
    List<string> list = new CopyOnWriteArrayList();
    
    for(int i = 1;i<=3; i++){
          new Thread(()->{
                list.add(uuid.randomUUID().tostring().substring(0,8));
                sout(list)
          }),String.valueOf(i).start();
    
    }
    

    collection和collections的区别
    collection是集合类的上层接口,collections是集合框架的工具类

    那arraylist存在的意义是什么呢?
    此时就涉及到 效率和安全了

    当遇到一致性为首要目的时,就需要用到vector
    当遇到效率作为首要目的时,就用到arraylist

    那CopyOnWriteArrayList 那为什么那么猛呢

    它读的时候共同读,写的时候单另写
    写完以后代替上一次版本,写的时候被读,读的是没写之前的/还是阻塞?,

    又迸发出来的小问题 ———— lock和 synchronize 的区别又是什么,reentrantlock和synchronized区别,volatile又是怎样的呢

    那set 安不安全
    不安全

    解决COW copyonwriteset
    hashset底层数据结构是什么

    hashmap,hashmap底层 是 数组 + 链表 + 红黑树
    hashset是hashmap的key的部分
    value是数组

    hashset的add
    hashset.add(E e) = map.put(e,PRESENT)== null

    list、set、map都线程不安全的

  • 相关阅读:
    腾讯招聘爬虫
    中华人民行政部网站爬虫
    百度翻译爬虫
    easyui 对form扩展
    Anaconda 安装和使用
    MongoDB基础教程系列--目录结构
    MongoDB基础教程系列--第九篇 MongoDB 分片
    MongoDB基础教程系列--第八篇 MongoDB 副本集实现复制功能
    MongoDB基础教程系列--第七篇 MongoDB 聚合管道
    MongoDB基础教程系列--第六篇 MongoDB 索引
  • 原文地址:https://www.cnblogs.com/nineberg/p/13530542.html
Copyright © 2011-2022 走看看