版权声明:本文为博主原创文章,允许转载,请标明出处。 https://blog.csdn.net/qwdafedv/article/details/84256291
前言
为什么要用线程池
经常创建、销毁 线程,将是对系统资源的极大浪费。 因此,实际开发中我们将使用线程池来管理、复用 线程。 使用线程池,可以 1.降低资源消耗: 重复利用线程,减少创建和销毁造成的消耗。 2.提升响应速度: 任务到达,不需要创建,立即执行。 3.提高可管理型: 线程是CPU调度和分派的基本单位, 如果无限制地创建,不仅会消耗系统资源,还会降低系统稳定性。 使用线程池可以统一进行 分配、调优和监控。
线程池的分类
ThreadPoolExecutor
ThreadPoolExecutor是线程池的真正实现, 他通过构造方法的一系列参数,来构成不同配置的线程池。 常用的构造方法有下面四个
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler);
- corePoolSize: 核心池的大小。 当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中
- maximumPoolSize: 线程池最大线程数,它表示在线程池中最多能创建多少个线程;
- keepAliveTime: 表示线程没有任务执行时最多保持多久时间会终止。
- unit: 参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性。
- workQueue:一个阻塞队列,提交的任务将会被放到这个队列里。
- threadFactory:线程工厂,用来创建线程,主要是为了给线程起名字,默认工厂的线程名字:pool-1-thread-3。
- handler:拒绝策略,当线程池里线程被耗尽,且队列也满了的时候会调用。
线程池的四种创建方式
Java通过Executors(jdk1.5并发包)提供四种线程池,分别为:
- newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 案例演示:
- newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
- newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
- newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程, 若无可回收,则新建线程。
package cn.qbz.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Test111907 { public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int temp = i; executorService.execute(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " i=" + temp); } }); } } }
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
package cn.qbz.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Test111907 { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); for (int i = 0; i < 10; i++) { final int temp = i; executorService.execute(new Runnable() { @Override public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " i=" + temp); } }); } } }
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
package cn.qbz.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Test111907 { public static void main(String[] args) { final long begin = System.currentTimeMillis(); ExecutorService executorService = Executors.newScheduledThreadPool(3); for (int i = 0; i < 10; i++) { final int temp = i; final long time = begin; executorService.schedule(new Runnable() { @Override public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " i=" + temp + " time=" + (System.currentTimeMillis() - time)); } }, 5, TimeUnit.SECONDS); } } }
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, new DelayedWorkQueue()); }
newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
package cn.qbz.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Test111907 { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); for (int i = 0; i < 10; i++) { final int temp = i; executorService.execute(new Runnable() { @Override public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " i=" + temp); } }); } } }