线程池原理
线程池底层使用**堵塞式队列 BlockingQueue
**。
队列遵从:先进先出,后进后出原则。
阻塞队列(BlockingQueue)和非阻塞队列(ConcurrentLinkedQueue )区别:
无界和有界队列:
ConcurrentLinkedQueue 是无界队列,不用设置长度,可以随便存放值(其实是jdk伪造的,最大长度是Integer的最大值)
BlockingQueue 是有界队列,需要设置长度。
注意:如果BlockingQueue 不设置等待时间就是非阻塞队列
存入:
非阻塞队列:如果存放超出了队列总数,添加不进去,就会丢失。
阻塞队列:如果存放超出了队列总数,进行等待,直到有队列出列,或者超时设置的等待时间)
获取:
非阻塞队列:如果为空时,返回空。
阻塞队列:如果为空时,进行等待,直到有新的队列入列,或者超过设置的等待时间
创建线程池的构造方法
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
ThreadPoolExecutor
参数说明
核心线程大小(corePoolSize)
最大线程大小(maximumPoolSize)
终止时间(keepAliveTime)
Unit 超时时间
workQueue 线程容器
自定义线程池
/**
* 自定义线程池
* @author terry
* @date 2018年5月28日
*/
public class ThreadExector3 {
public static void main(String[] args) throws Exception {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1,//核心线程
1,//最大线程
0L,//超时时间
TimeUnit.SECONDS,
new LinkedBlockingQueue<>()
);
pool.execute(new Task("任务一"));
pool.execute(new Task("任务二"));
pool.execute(new Task("任务三"));
pool.execute(new Task("任务四"));
pool.shutdown();
}
}
class Task extends Thread{
private String name;
public Task(String name){
this.name = name;
}
public void run(){
System.out.println(Thread.currentThread().getName()+"正在执行,"+name);
}
}
如果限制容器长度会报错:
new LinkedBlockingQueue<>(2)