1线程池中提交一个任务得流程是怎样的

源代码
public void execute(Runnable command) {if (command == null)throw new NullPointerException();/** Proceed in 3 steps:** 1. If fewer than corePoolSize threads are running, try to* start a new thread with the given command as its first* task. The call to addWorker atomically checks runState and* workerCount, and so prevents false alarms that would add* threads when it shouldn't, by returning false.** 2. If a task can be successfully queued, then we still need* to double-check whether we should have added a thread* (because existing ones died since last checking) or that* the pool shut down since entry into this method. So we* recheck state and if necessary roll back the enqueuing if* stopped, or start a new thread if there are none.** 3. If we cannot queue task, then we try to add a new* thread. If it fails, we know we are shut down or saturated* and so reject the task.*/int c = ctl.get();if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);}else if (!addWorker(command, false))reject(command);}
2 线程池中有几种状态?分别是如何变化的?
状态:
1 RUNNING: 会接收新任务并且会处理队列中的任务
2 SHUTDOWN:不会接收新任务并且会处理队列中的任务,任务处理完后会中断所有线程
3 STOP: 不会接收新任务并且不会处理队列中的任务,并且会直接中断所有线程
4 TIDYING:所有线程都停止之后,线程池的状态会转为TIDYING,一旦达到此状态,就会调用线程池的terminated()
5 TERMINATED: terminated()执行完之后就会转变为TERMINATED
源码:
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));private static final int COUNT_BITS = Integer.SIZE - 3;private static final int CAPACITY = (1 << COUNT_BITS) - 1;// runState is stored in the high-order bitsprivate 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;

3 如何优雅的停止一个线程
stop():stop()会释放线程占用的synchronized锁,而不会自动释放ReentranLock锁
interrupt(): 该方法只是在目标线程中设置一个标志,表示它已经被中断,线程是否中断,取决于线程本身,
4 线程池的核心线程数,最大线程数如何设置?
对于cpu密集型任务: cpu核心数+1
io型任务: 2*cpu核心数
cpu核心数 * (1 + 线程等待时间 / 线程运行总时间 )
可以使用jvisualvm来估算这两个时间
corePoolSize: 核心线程数,表示线程中的常驻线程个数
maximumPoolSize: 最大线程数,表示线程池总能开辟的最大线程个数
核心应用():核心线程数 = maximumPoolSize = 压测出来的个数,
非核心线程:核心线程数设置少点,maximumPoolSize=压测个数
5 如何理解java并发中的可见性
java 并发可见性是指多线程并发访问共享变量时,对变量的更改能够被其他线程及时感知
可以使用volatile关键字来保证变量的可见性