Java多线程与高并发
2022-10-31 21:39:50 0 举报
AI智能生成
Java多线程与高并发
作者其他创作
大纲/内容
测试工具:JMH
数据结构
基本概念
定义事件
定义事件对象生成的工厂
定义消费者
开始使用
基本使用
Disruptor
高频面试加分项
接口说明
说明:只有一个线程执行的方法
Executor
说明:完善了线程池的生命周期
ExecutorService
newCachedThreadPool
newFixedThreadPool
newSingleThreadExecutor
newScheduleThreadPool
JDK提供的4中线程创建方式
基础
corePoolSize
maxmumPoolSize
keepAliveTIme
TimeUnit
BlockQueue
ThreadFactory
抛出RejectedExecutionException异常(默认)
AbortPolicy()
抛弃当前的任务
DiscardPolicy()
抛弃最旧的任务(最先提交而没有得到执行的任务)
DiscardOldestPolicy()
由向线程池提交任务的线程来执行该任务
CallerRunsPolicy()
常见四种策略(可自定义)
RejectStrategy
参数介绍
RUNNABLE
状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。
SHUTDOWN
STOP
状态切换:当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。
状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。
TIDYING
状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED
TERMINATED
线程池的五种状态
ThreadPoolExecutor
核心
ForkJoinPool
线程池
继承Thread类
实现Runnable接口
lambda表达式
原理:方法阻塞的原理是LockSupport
线程如果被取消了(调用了cancel()方法),则获取不了结果,并抛出异常
get()
isDone()
true
false
cancel(boolean)
isCancelled()
实现Callable接口
线程池方式
五种创建线程的方式
线程状态 --> 等待状态
注意:但不会释放锁
[static] sleep(ms)
线程状态 --> 就绪状态
说明:将线程重新放进等待队列中
[static] yield()
让该线程等待另一个线程执行
注意:会释放锁
join()
获取线程的状态
status()
说明:使当前对象Object进入阻塞,并释放锁
wait()
说明:唤醒该对象Object,但不释放锁
notify()
notifyAll()
wait()与nofiy()
说明:线程暂停
suspend()
说明:线程启动
resume()
suspend()与resume()
说明:线程打断,其实就是给线程跑出打断的异常,设置打断的标志位。
interrupt()
static interrupted()
线程打断(其实设置标志位)
说明:线程停止
stop()
线程停止的方法
Callable
FutureTask
Callable和FutureTask
线程的常用方法
线程刚刚创建,还没有启动
NEW
可运行状态,由线程调度器可以安排执行
RUNABLE
等待被唤醒
WAITING
隔一段时间后自动唤醒
TIMED WAITING
被阻塞,正在等待锁
BLOCKED
线程结束
TERMINATED
6种线程状态
JDK自带的原子类
自旋锁
适用:线程数量多
特点:分段锁
LongAdder
应用案例
解决方案:AtomicStampedReference类
ABA问题
CAS
使用案例:Person person = new Person
说明:垃圾回收机制,在发现引用的时候,不会被回收
强引用
使用案例:SoftReference<Person> person = new SoftReference<>(new Person())
说明:垃圾回收机制,且内存不够用时,会被回收
缓存
应用
软引用
使用案例:WeakReference<Person> person = new WeakReference<>(new Person())
说明:垃圾回收机制,该对象会被立即回收
一般用在容器中
ThreadLocal
弱引用
虚引用
四种引用
基础概念
偏向锁
线程数量少,且执行时间短
适用场景
特点:占用CPU资源
自旋锁(CAS)、乐观锁
线程数量多,或执行时间长
重量级锁
可重入锁
不可重入锁
分类:重入性
共享锁(读)
排它锁(写)
读写锁
锁的种类
偏向锁:给对象所,添加标识
自旋锁:CAS(自旋10次就升级)
锁升级过程
唯一一个能让线程进入BLOCKED状态的锁
特点
锁的细化
锁的粗化
优化
用法
synchronized()
lock()
unlock()
使用tryLock进行尝试锁定,不管锁定与否,方法都将继续执行可以根据tryLock的返回值来判定是否锁定也可以指定tryLock的时间,由于tryLock(time)抛出异常,所以要注意unclock的处理,必须放到finally中
trylock()
可以对 interrupt()方法做出相应(被打断)
lockInterruptibly()
创建新的等待队列
newCondition()
true --> 公平锁
false --> 不公平锁(默认)
构造方法传入boolean值
用方
原理
ReenrantLock
基于CAS的锁
ReentrantReadWriteLock
实现子类
readLock()
writeLock()
ReadWriterLock
Lock
MESI
缓存一致性协议
保证线程可见性
禁止指令重排序
用途
JVM向内存申请空间
初始化成员变量
将对象赋值给相应的变量
对象创建NEW过程
变量应该加上 volatile
懒汉式单例创建
volatile
分段锁
说明:让当前线程`停车`
park()
说明:指定某个线程`开车`
参数1:Thread
unpark(Thread)
注意:但不能先与Thread.start()方法调用
unpart()可以先于part()调用
1. 使用 unpark(Thread)时,该线程必须处于启动状态(start()状态),否则使用park()时,会被一直阻塞。
说明
LockSupport
线程锁
说明:需要提前准备好,才能继续执行
说明:需要执行的线程数量
构造函数(传入整形数值)
说明:需要执行的线程数量 - 1
countDown()
说明:等待需要执行的线程数量为0的时候
await()
CountDownLatch
说明:需要全部准备好了,才能一起同时干活
参数1:需要多少个线程
参数2:Runnable实现类(可选)
构造函数
说明:n个线程准备就绪后,进行后续操作
如果没有足够多的线程,也可以,通过该方法进行执行
reset()
可以重复使用()
通过 ReentrantLock 实现锁安全,Condition 实现等待阻塞
限流
运动员比赛
CyclicBarrier
说明:阶段。(CountDownLatch的升级版本)
说明:当前阶段还需要执行的线程数量-1
arriveAndAwaitAdvance()
说明:当前阶段且之后所有阶段需要执行的线程数量-1
arriveAndDeregister()
说明:当前阶段且下一个阶段需要执行的线程数量-1
arrive()
案例
遗传算法
Phaser
说明:信号量
说明:最大允许的信号量数量
参数1:int
说明:指定是否是公平锁(默认false,非公平锁)
参数2:boolean(可选)
说明:信号量 -1(当不够的时候,进入阻塞状态)
注意:不释放锁
acquire()
说明:信号量 +1,但如果信号量满了,不会有任何操作
release()
Semaphore
说明:数据交换
说明:指定线程之间交换数据的类型
指定泛型
说明:线程的数据之间进行交换(阻塞的)
exchange()
微信的摇一摇
实现原理
Exchanger
线程之间的通信
与当前线程有关(当前线程的ThreadLocalMap有关)
在对象不再需要使用时,应该调用 remvoe() 方法
注意:
重要类及说明
JUC同步工具
线程同步锁AQS实现
Collection
说明:自带锁,目前基本不用
Vector
Hashtable
CopyOnWriteList
ConcurrentHashMap
ConcurrentSkipListMap
同步容器
常见容器
Java多线程与高并发
收藏
0 条评论
回复 删除
下一页