集合类不安全

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都线程不安全的

原文地址:https://www.cnblogs.com/nineberg/p/13530542.html