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