ThreadPoolExecutor

参数

1
2
3
4
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
TimeUnit unit, BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory, RejectedExecutionHandler handler);

  • corePoolSize: 线程池核心线程的数量;
  • maximumPoolSize: 线程池可创建的最大线程数量;
Read More

ThreadPoolExecutor原理分析

线程池状态

1
2
3
4
5
6
7
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;

当创建线程池后,初始时,线程池处于 RUNNING 状态;
如果调用了 shutdown()方法,则线程池处于 SHUTDOWN 状态,此时线程池不 能够接受新的任务,它会等待所有任务执行完毕;
如果调用了 shutdownNow()方法,则线程池处于 STOP 状态,此时线程池不能 接受新的任务,并且会去尝试终止正在执行的任务;
当线程池处于 SHUTDOWN 或 STOP 状态,并且所有工作线程已经销毁,任务缓 存队列已经清空或执行结束后,线程池被设置为 TERMINATED 状态。

任务的执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private final BlockingQueue<Runnable> workQueue;//任务缓存队列,用来存放等待执行的任务
private final ReentrantLock mainLock = new ReentrantLock();//线程池的主要状态锁,对线程池状态(比如线程池大小、runState 等的改变都要使用这个锁)
private final HashSet<Worker> workers = new HashSet<>();//用来存放工作集
private volatile long keepAliveTime;//线程存货时间
private volatile boolean allowCoreThreadTimeOut;//是否允许为核心线程设置存活时间
private volatile int corePoolSize;//核心池的大小(即线程池中的线程数目大于这 个参数时,提交的任务会被放进任务缓存队列)
private volatile int maximumPoolSize;//线程池最大能容忍的线程数

public int getPoolSize(){}//获取当前线程池的线程数量
private volatile RejectedExecutionHandler handler;//任务拒绝策略
private volatile ThreadFactory threadFactory;//线程工厂,用来创建线程
private int largestPoolSize;//用来记录线程池中曾经出现过的最大线程数
private long completedTaskCount;//用来记录已经执行完毕的任务个数

最核心的任务提交方法是 execute()方法,虽然通 过 submit 也可以提交任务,但是实际上 submit 方法里面最终调用的还是 execute()方法

Read More

volatile

volatile作用

在Java并发编程中,volatile 是经常用到的一个关键字,它可以用于保证不同的线程共享一个变量时每次都能获取最新的值。volatile具有锁的部分功能并且性能比锁更好,所以也被称为轻量级锁。

一个变量被volatile修饰,则:

  1. 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
  2. 禁止进行指令重排序。
Read More

Thread

Java中的Thread的用法

同步队列与等待队列

  • 同步队列:所有尝试获取该对象Monitor失败的线程,都加入同步队列排队获取锁。调用了start、notify方法后会进入该队列。

  • 等待队列:已经拿到锁的线程在等待其他资源时,主动释放锁,置入该对象等待队列中,等待被唤醒,当调用notify会在等待队列中任意唤醒一个线程,
    将其置入同步队列的尾部,排队获取锁。调用wait方法时,会进入该队列。

Read More