java多线程
Java 多线程
java进程间通信: JMI, 进程间通过serialize java对象通信
java thread相关api: thread, runnable, ...
- juc的executor系列api
synchronized 修饰方法: 实则是在锁this
- 锁在有其他注解的地方: 危险! 需要注意
- 到底锁的是对象还是代理对象(例如在synchronized范围内, 调用一个@Transaction修饰的方法, @Transaction实际上是通过proxy类实现的, 所以必须显式拿到proxy object才能被synchronized锁住)
- 某些注解是否支持锁
- 细粒度锁: 例如锁字符串的问题, 锁在对象还是字符串字面值?后者
toString().intern()
锁在常量池的字面量对象
synchronized 的核心: 监视器锁, 每个对象都有, 排它的
- 锁升级: 无锁
->
偏向锁->
自旋锁->
重量级锁
volatile语义类似cxx, 只保证可见性, 不保证原子性(java原子类是AtomicXXX, 实质上是通过unsafe指针操作对给定内存地址CAS)
- (JMM) 所有可能出现竞争的变量(成员, 静态等)均在主内存, 局部变量线程私有, 工作内存相互隔离, 只能通过主内存同步
死锁, 活锁, 饿死 老概念了
不可变数据结构: 例如CopyOnWriteArrayList
其他并发容器还有 ConcurrentLinkedQueue 并发队列,ConcurrentSkipListMap 并发跳表,ConCurrentHashMap 并发哈希表之类
线程池
public ThreadPoolExecutor(int corePoolSize,//线程池的核心线程数量
int maximumPoolSize,//线程池的最大线程数
long keepAliveTime,//当线程数大于核心线程数时,多余的空闲线程存活的最长时间
TimeUnit unit,//时间单位
BlockingQueue<Runnable> workQueue,//任务队列,用来储存等待执行任务的队列
ThreadFactory threadFactory,//线程工厂,用来创建线程,一般默认即可
RejectedExecutionHandler handler//拒绝策略,当提交的任务过多而不能及时处理时,我们可以定制策略来处理任务
)
几个实现:
FixedThreadPool
:固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。
SingleThreadExecutor
: 只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。
CachedThreadPool
: 可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。
ScheduledThreadPool
:给定的延迟后运行任务或者定期执行任务的线程池
ForkJoinPool
: 自动计算线程池参数, 并自动工作窃取(CompeletableFuture系列API的底层默认实现)
虚拟线程: 用户态线程 = 携程, jdk21, Thread.ofVirtual()