一、线程安全
什么是线程不安全?
当多线程在访问同一个对象时,会因为其他线程的存在而获得错误结果,则该对象非线程安全。
线程安全的三要素?
有序性(volatile)+可见性(volatile)+原子性(由CAS提供硬件级别的原子操作)
二、线程池是如何实现线程复用?
线程池是对线程和任务的解耦,避免一个thread必须对应一个task的限制。
//一个字段表示两个含义:高3位=runState,低29位=workerCount
final AtomicInteger ctl
BlockingQueue<Runnable> workQueue
HashSet<Worker> workers
volatile ThreadFactory threadFactory;
volatile RejectedExecutionHandler handler;
volatile long keepAliveTime;
volatile int corePoolSize;
volatile int maximumPoolSize;
public void execute(Runnable command) {
addWorker(command, true);
}
boolean addWorker(Runnable firstTask, boolean core) {
Worker w = new Worker(firstTask);
Thread t = w.thread;
//启动线程
t.start();
}
class Worker extends AbstractQueuedSynchronizer implements Runnable {
final Thread thread; //被复用的线程
Runnable firstTask; //循环获取后被执行的任务
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
public void run() {
runWorker(this);
}
}
void runWorker(Worker w) {
//先执行第一个任务
Runnable task = w.firstTask;
//循环从队列中获取待执行任务
while (task != null || (task = getTask()) != null) {
//直接对run方法调用
task.run();
//执行结束后销毁,从队列中获取下一个任务
task = null;
}
}
//从等待队列中获取任务
Runnable getTask() {
for (;;) {
return timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
}
}