ThreadPool
什么是线程池?
线程池就是一个线程缓存,负责对线程进行统一分配、调度与监控。
线程池的意义?
线程是稀缺资源,它的创建和销毁比较重且消耗资源,而java线程依赖于内核线程,创建线程需要进行操作系统状态切换,为避免资源过度消耗需要设法重用线程执行多个任务。
线程池的优势?
重用存在的线程,减少线程创建,消亡的开销,提高性能
提高响应速度。当任务到达时,任务可以不需要等到线程创建,就能立即执行
调高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性。
线程池是怎么创建线程的?
线程池默认初始化不启动Woeker,等待有请求时才启动,每当调用execute()方法添加一个任务时,线程池会做如下判断:
当前运行线程数量小于corePoolSize,则立即创建这个任务;大于或等于corePoolSize则将任务放入队列中;如果队列满了且正在运行的线程数量小于maximumPoolSize,则创建非核心线程立即运行这个任务;否则抛出异常RejectExecutionException。
线程池的五种状态?
Running:能接收新任务,以及处理已经添加的任务
Shutdown:不接收新任务,可以处理已经添加的任务
Stop:不接收新任务,不出来已经添加的任务,并且中断正在处理的任务
Tidying:所有的任务已经终止,ctl记录的任务数量为”0“(ctl负责记录线程池的运行状态与活动线程数)
Terminated:线程池彻底终止,则线程池转化为terminated状态
线程池为什么不允许使用Executors去创建,而是通过ThreadPoolExecutor的处理方式?
使用ThreadPoolExecutor的方式创建线程池可以使开发者更加明确线程池的运行规则。
使用Executors的弊端:FixedThreadPool和SingleThreadPool允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致服务响应阻塞。
CachedThreadPool和ScheduledThreadPool允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的西安城,从而导致cpu崩溃。
1 public static void main(String[] args) { 2 3 final ExecutorService pool= new ThreadPoolExecutor(2, 4 3, 5 60, 6 TimeUnit.SECONDS, 7 new ArrayBlockingQueue<Runnable>(5), 8 Executors.defaultThreadFactory()); 9 10 try { 11 12 for (int i = 0; i < 9; i++) { 13 14 pool.execute(new Runnable() { 15 @Override 16 public void run() { 17 18 System.out.println("1"); 19 } 20 }); 21 22 } 23 24 }catch (Exception e){ 25 26 27 } 28 29 final ExecutorService pool1=Executors.newFixedThreadPool(1); 30 final ExecutorService pool2=Executors.newSingleThreadExecutor(); 31 final ExecutorService pool3=Executors.newCachedThreadPool(); 32 final ExecutorService pool4=Executors.newScheduledThreadPool(1); 33 final ExecutorService pool5=Executors.newWorkStealingPool(); 34 }