ThreadPoolExecutor构造参数:.corePoolSize
:核心线程数,默认核心线程会一直存活, ThreadPoolExecutor。allowCoreThreadTimeOut为true时,闲置的核心线程在keepAliveTime后可被终止;
.maximumPoolSize
:最大线程数,当活动线程数达到这个数值后,后续的任务将会被阻塞;
.keepAliveTime
:核心线程闲置时(wait状态)的超时时长;
.unit
:keepAliveTime时间单位,TimeUnit.MILLISECONDS
、TimeUnit.SECONDS
、TimeUnit.MINUTES
等;
.workQueue
:任务队列,通过线程池的execute方法提交的Runnable对象会存于其中
.threadFactory
:创建新线程,接口,newThread(Runnable r)
; //Callable
.RejectedExecutionHandler
:线程池无法执行新任务时,可能是由于任务队列已满或是无法成功执行任务,这时就会调用这个Handler的rejectedExecution
方法来反馈,默认rejectedExecution
会直接抛出rejectedExecutionException
。
1.如果线程池中的线程数未达到核心线程的数量,那么会直接启动一个核心线程来执行任务;
2.如果线程池中的线程数量已达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等待;
3.如果在步骤2中无法将任务插入到的任务队列中,可能是任务队列已满,这时如果线程数量没有达到规定的最大值,那么会立刻启动非核心线程来执行这个任务;
4.如果3中线程数量已经达到线程池规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor会调用RejectedExecutionHandler
的rejectedExecution
方法
shutdown():等所有任务缓存队列中的任务都执行完后才终止,SHUTDOWN,且不接受新任务;shutdownNow(),STOP Thread.sleep(0)可使OS重配时间片。 volatile poolRunState;
CPU密集型任务,如 NCPU(Runtime.getRuntime().availableProcessors())+1;IO密集型任务,如2*NCPU
.FixedThreadPool
:LinkedBlockingQueue,只有核心线程,线程池不主动关闭线程们,经常待命以快速响应请求;
.ScheduledThreadPool
:DelayedWorkQueue(DelayQueue. extends AbstractCollection<Runnable>implements BlockingQueue<Runnable>),核心线程数量固定,非核心线程数量没限制,主要用于执行定时或周期性任务;可代Timer.schedule();
.SingleThreadPool
:LinkedBlockingQueue,只一个线程,任务们队列化。如大量数据:Executors.newSingleThreadExecutor().execute(newRunnable(){
@Override public void run(){
db.insert(tableName,null,value);
}
});
.CachedThreadPool
:线程数量不固定,SynchronousQueue<Runnable>,60s的超时机制,立即执行,大量耗时少的任务;
线程结束:run方法执行完;(stop(stop是通过立即抛出ThreadDeath异常,来达到停止线程的目的,此异常抛出有可能发生在任何一时间点,包括在catch、finally等语句块中,但是此异常并不会引起程序退出(只测试了Java8)。
由于有异常抛出,导致线程会释放全部所持有的锁,极可能引起线程安全问题);①将释放该线程所持的所有锁,而且锁的释放不可控。②抛出ThreadDeath异常,但它不总是有效,如果存在被终止线程的锁竞争;一将导致数据一致性问题,一般数据加锁就是为了保护数据的一致性,而线程停止伴随所持锁的释放,很可能导致被保护的数据呈现不一致性,最终导致程序运算出现错误。二是可能存在某种情况stop()方法不能及时终止线程,甚至可能终止不了线程,比如某方法使用了synchronized修饰,表示在执行其时将对某对象加锁,另外,Thread的stop()方法也是同步的,于是在调用某线程的stop()方法前必须获取对象锁,但对象锁被同步方法占用,且不释放,于是stop()方法永远获取不了对象锁,于是。)
run() {
while(true){//持久线程
work();
if(shouldFinish){//结束条件
break;
}
/* try {
Thread.sleep(9999);//
} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
}在while死循环内,每次循环时,察看外部条件。符合条件就break跳出死循环,或抛出异常,跳出死循环;
捕获InterruptedException,中断当前线程:run() {
while(true){
try {
// 阻塞型任务
//其它thread对象调interrupt() 产生以下异常
} catch (InterruptedException e) {
throw new RuntimeException();//或break;结束该线程
}
work();
}
if(尝试获取锁失败) {
创建node
使用CAS方式把node插入到队列尾部
while(true){
if(尝试获取锁成功并且 node的前驱节点为头节点){
把当前节点设置为头节点
跳出循环
}else{
使用CAS方式修改node前驱节点的waitStatus标识为signal
if(修改成功){
挂起当前线程
if(当前线程中断位标识为true)
抛出InterruptedException异常
}
}
}
//updating
Explicity Lock(显式) 原子变量 局部变量 final static 同步容器
AbstractQueuedSynchronizer:
ReentrantLock/synchronized:
volatile:并不保证同步,不具有操作的原子性,不适合在对变量的写操作依赖于域本身(如i++、i+=1;), 不适合受到其它域限制
AtomicInteger,轻量级的synchronized,Lock-Free算法。高并发时效率比synchronized高些
浅复制:clone(), System.ArrayCopy()
同步:final Object。wait( Thread.wait()释放线程对锁的拥有权(对象的锁())等到另一线程调用notify(All)()唤醒以便争取锁;确保调用wait()方法的时候拥有锁,须在非抽象synchronized方法或synchronized块中,或Class对象的synchronized、static方法。Thread.sleep() )与notify(唤醒某个等待当前对象的锁的线程/All)(被拥有对象的锁的线程调用)
:域超栈的量的"下一刻“的值
:端与端间的交互, “下一刻”的结果