JAVA 多线程和锁
2022-05-26 16:24:16 0 举报
AI智能生成
多线程和锁知识架构图
作者其他创作
大纲/内容
集合
不安全(单个线程操作)
Collection
AbstracetCollection
List
AbstractList
LinkedList
使用链表,插入和删除速度快
foreach最快
ArrayList
使用数组,随机查询速度快
默认容量大小是10
新的容量=“(原始容量x3)/2 + 1”
通过System.arraycopy进行扩容
通过get(i)遍历最快
Vector
Stack
使用synchronized方法同步实现线程安全,速度慢
Set
AbstractSet
HashSet
通过HashMap实现,value为null
TreeSet
通过TreeMap实现
Map
AbstractMap
HashMap
默认容量大小是16
默认扩容因子0.75,达到0.75就会进行扩容
通过entryset遍历最快
TreeMap
红黑树实现
WeakHashMap
HashTable
使用synchronized方法同步实现线程安全,速度慢
安全(可多个线程同时操作)
List
CopyOnWriteArrayList
对数据组进行snapshot,然后在进行操作,最后进行复制合并
元素不多,少改,多查
遍历时使用snapshot,速度快
不支持可变Remove()
内部使用volatile数组”(array)来保持数据。在“添加/修改/删除”数据时,都会新建一个数组,并将更新后的数据拷贝到新建的数组中,最后再将该数组赋值给“volatile数组”,通过互斥锁保证安全,通过独占锁,来防止多线程同时修改数据
Set
CopyOnWriteArraySet
通过CopyOnWriteArrayList实现
ConcurrentSkipListSet
通过ConcurrentSkipListMap实现
Map
ConcurrentHashMap
通过“锁分段”来实现
内部结构是维护一个HashEntry的数组,put时,对key进行hash,获取hash在entry数组上的index,然后对当前index的entry进行操作,entry是一个单向链表,可以存储多个映射并形成单向链表。Entry数组的访问和元素之间的操作可以是并发的,每个元素都是一个hash段的entry,并持有一个可重入的锁,防止对当前元素进行并发操作。
ConcurrentSkipListMap
通过“跳表”来实现
对key进行分层排序,通过在最高层向下按区间最快查找到元素,如一排10个木桩,高矮不一,有序
Queue
BlockQueue
ArrayBlockingQueue
LinkedBlockingQueue / Deque
ConcurrentLinkedQueue / Deque
LinkedTransferQueue
工具类
Arrays
Collections
System.arraycopy
线程池
ThreadPoolExecutor
BlockingQueue<Runnable> workQueue
用户提交的需要执行的线程缓存队列
HashSet<Worker> workers = new HashSet<Worker>();
第个Worker是一个线程,通过Worker线程获取workQueue里面的用户线程进行执行
corePoolSize / maximumPoolSize / keepAliveTime
控制Worker的创建和销毁
handler
AbortPolicy(默认)
RejectedExecutionException
CallerRunsPolicy
DiscardOldestPolicy
使用线程池正在运行的线程执行当前任务
DiscardPolicy
mainLock
互斥锁,控制对workers的访问
钩子函数
terminated
afterExecute
beforeExecute
线程
Thread / Callable / Runnable
线程状态
新建(new)
对象创建
就绪(start)
调用start()方法后随时准备cpu执行
不能重复调用start
执行(running)
获取CPU进行执行,只能坐吃山空就绪到执行
run被线程执行,也可手动执行run在当前线程中执行了一个方法 调用,不会新建线程执行
阻塞(block)
wait() / synchronized / sleep() /join() 等操作导致的阻塞,阻塞时有的释放锁,有的继续持有锁
停止(dead)
run()结束或异常终止
分类
守护线程(Daemon)
用户线程(用户新建/main()/pool)
线程安全
多个线程同时操作是否能获取预期的结果
常用方法
interrupt()
isInterrupt()
锁
Object
wait
notify
分类
同步锁
synchronized
对象方法
代码块
静态方法
JUC锁
Lock
ReentrantLock
ReadWriteLock
ReentrantReadWriteLock
ReadLock
WriteLock
StampedLock
AQS抽象
AbstractQueuedSynchronizer
LockSupport
park/unpark 解决Thead 死锁
Condition
Sync
CLH
CLH队列是AQS中“等待锁”的线程队列
CAS函数
CAS函数,是比较并交换函数,它是原子操作函数,直接操作内存,操作不中断
常用
独占锁
ReentrantLock
定义:锁在一个时间点只能被一个线程锁占有
公平锁
非公平锁
ReentrantReadWriteLock里的WriteLock
共享
ReentrantReadWriteLock里的ReadLock
能被多个线程同时拥有,能被共享的锁
CyclicBarrier
循环栅栏,初始时设定参与线程数,当线程到达栅栏后,会等待其它线程的到达,当到达栅栏的总数满足指定数后,所有等待的线程继续执行
CountDownLatch
倒数计数器,初始时设定计数器值,线程可以在计数器上等待,当计数器值归0后,所有等待的线程继续执行
Semaphore
访问共享资源的许可证
Exchanger
两个线程之间的数据交换
Phaser
多阶段栅栏,可以在初始时设定参与线程数,也可以中途注册/注销参与者,当到达的参与者数量满足栅栏设定的数量后,会进行阶段升级(advance)
CAS原子类
在32位操作系统中,64位的long 和 double 变量由于会被JVM当作两个分离的32位来进行操作,所以不具有原子性。通过Unsafe的CAS函数和volatile 特性直接操作系统内存实现对基本类型的累加/引用类型的变更/对象属性的变更/数组元素的修改
基本类型
AtomicLong-Integer-Boolean
LongAdder
数据类型
AtomicLong-Integer-Reference-Array
引用类型
AtomicReference/AtomicStampedRerence/AtomicMarkableReference
对象属性修改
Atomic-Long-Integer-Reference-FieldUpdater
0 条评论
下一页