Skip to main content

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()