1. JUC大纲
2. volatile关键字 内存可见性
一 . JVM会为每一个执行任务线程分布一个独立缓存
二. 线程在读写主存的共享数据时,需先将主内存数据加载到自己独立内存中
无volatile关键字保证
三 . 有volatile关键字保证,直接对主存中的数据进行读写,但效率也有变低,因为jvm底层中有个优化,叫做重排序,用volatile修饰后无法重排序
四. volatile相对于synchronized是一种较为轻量的同步策略
1. volatile 不具备“ 互斥性“ 多个线程可对共享数据同时行读写,synchronized斥性是指,一个锁只能让一个线程读写,
2. volatule不能保证变量”原子性”
总结:
在程序中被volatile关键字修饰后,使数据可见,各个线程不再是从主内存中复制到自己独立内存中读写,而是直接在主内存中读写,但它不具备synchronized的互斥性,可以允许多个线程同时对其进行读写,不具备原子性
3. 原子变量与CAS算法
一 . i++ 的原子性问题:i++ 操作实际分为 读改写三步
如果用volatile修饰,也只是将三步骤在主内存中运算,但它没有互斥性,多线程可同时对数据进行读写,因此不支持原子性
二.原子变量:jdk1.5之后java.util.concurrent.atomic包写提供了常用的原子变量:
1. volatile保证内存可见性
2. CAS(Compare-And_Swap) 数据的原子性
3. CAS算法是硬件对并发操作共享数据的支持
4. 包含了三个操作数
5. 内存值 V 预估值 A 更新值 B
6. 多个线程对数据进行读写,需进行CAS三步操作,只有当要修改时的数据A与,最原来读的值相同才会将B进行赋值,否则什么都不做,并再去重新访问,效率比同步锁更高
4. CAS算法模拟
5. 同步容器ConcurrentHashMap(线程安全的hash表)
Hashtable锁表,效率极低,并行转换为串行,安全但不采用
有复合操作
“不存在则添加”
“若存在则删除”
一 .ConcurrentHashMap采用“锁分段”机制
concurrentLevel:分段级别,默认十六,Segment段
每个段都是独立的锁,并且安全,但1.8之后全变成了CAS算法来代替
hash算法
hashMap中的put方法里的putVal方法,下 注意resize()方法(为初始化或扩容数组)为数组长度, index= e.hash&(newCap-1)
https://blog.csdn.net/weixin_43861942/article/details/90346364
CopyOnWriteArrayList
并发修改异常,使用写入并复制,可以解决,每次都复制效率低,
适合迭代操作,
6. CountDownLatch闭锁
主线程与分线程同时执行,无法算出耗费时间,
7.创建线程的第三种方式:实现Callable接口
实现callable,相对于实现runnable,有返回值,有抛出异常
执行callable方式是,需要futureTask实现类的支持,用于接受结果
FutureTask可用于闭锁,只有当线程执行完成后,才能进行下一步
Future内部实现了runnable
8.同步锁
更加灵活,更加方便的锁
Condition
线程程序交替ABC
创建一个类,lock同步锁来保持线程安全,创建四个线程通讯condition与四个方法,依次循环唤醒
读写锁ReadWriteLock
线程八锁
静态方法的锁对象为.class的实例,非静态方法锁为this
线程池
四种方法:newfixedThreadPool(),newScheduledThreadPool(),newCachedThreadPool(),newSingleThreadPool()
pool.submit提交给线程分配任务 关闭pool.shutdown