各位小伙伴看本博客之前,可以根据自身情况复习一下多线程,这是我自己总结的笔记https://blog.csdn.net/ls_wifi/article/details/106849602
JUC(java.util.concurrent):三个包
java.util.concurrent
java.util.concurrent.atomic
java.util.concurrent.locks
如何编写 企业级的多线程代码
1.在高内聚低耦合的前提下,线程 操作 资源类
2.判断/干活/通知
3. 防止虚假唤醒(判断用while)
中断和虚假唤醒是可能产生的,所以要用loop循环,if只判断一次,while是只要唤醒就要拉回来再判断一次。if换成while
1.1 先创建一个资源类(高内聚就是资源类自身携带这些方法而不是外部提供,低耦合就是减少方法之间的调用)
NEW RUNNABLE BLOCKED WAITING(死等,不见不散) TIME_WAITING(等到多少秒后你不理我我就撤,过时不候) TERMINATED
lambda表达式写法: 拷贝小括号,写死右箭头,落地大括号
@FunctionalInterface (函数式接口显式定义)
Jdk8及以后,允许我们在接口中定义static方法和default方法(均为方法体)
Java8 new一个ArrayList底层是new了一个初始值为10的Object类型的数组 16是HashMap
ArrayList的扩容是原值的一半,HashMap的扩容是原值的一倍
java.util.ConcurrentModificationException 并发修改异常
解决方法: 1.new Vector<>()
2.Collections.synchronizedList(new ArrayList<>())
3.new CopyOnWriteArrayList() //CopyOnWriteArraySet<>() ConcurrentHashMap<K,V>()
Collection是接口 Collections是集合接口的工具类
CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将Object[]进行copy,复制出一个新的容器Object[] newElements,然后新的容器Object[] newElement里添加元素,添加完元素之后,再将原容器的引用指向新的容器 setArray(newElements); 这样做的好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器
TimeUnit.SECONDS.sleep(4); 相当于Thread.sleep(4000)
八锁理论解释:(一二锁)一个对象里面如果有多个synchronized方法,某一时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程只能等待,换句话说,某一时刻内,只有唯一一个线程去访问这些synchronized方法,锁的是当前对象this(俗称对象锁),被锁定后,其它的线程都不能进入到当前对象的其它的synchronized方法
加个普通方法后发现和同步锁无关(三锁)
换成两个对象后,不是同一把锁了,情况立刻变化(四锁)
对于静态同步方法,锁的是当前类的Class对象。(五六七八锁 【全局锁】)