线程池
什么是线程池?
1、线程池是一个线程容器,可以设置线程分配的数量上限。 2、将预先创建的线程对象放入线程池,并重用线程池中的线程对象。 3、避免频繁的创建和销毁线程。
为什么使用线程池?
1、线程是宝贵的内存资源,单个线程约占1MB空间,过多分配容易造成内存溢出。 2、频繁的创建、销毁线程会增加虚拟机回收频率、资源开销,造成程序性能下降。
线程池工作原理
将任务提交给线程池,由线程池分配线程、运行任务,并在当前任务结束后复用线程。
常用的线程池接口和类(所在包 java.util.concurren)
Executor:线程池的顶级接口。 ExecutorService:线程池接口,继承了Executor,并新增了一些用于任务提交及管理的一些方法,例如任务的提交、任务的停止等。 ThreadPoolExecutor:线程池中最核心的一个类,继承了AbstractExecutorService,它是线程池最具体的实现,因为它实现了Executor中所定义的execute ()方法。 ScheduledThreadPoolExecutor:可以实现定时任务的线程池。 Executors:通过此类可以帮助我们创建线程池: 1、newCachedThreadPool:创建一个可缓存的线程池,线程的数量根据我们传入的任务数量发生改变。 2、newFixedThreadPool:创建一个定长的线程池,可控制最大并发量。 3、newScheduledThreadPool:创建一个定长的线程池,可用于指定定时或周期任务。 4、newSingleThreadPool:创建一个单线程的线程池,它只会用唯一的工作线程来执行任务。 注: 线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式。 这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()等创建线程池的方法,但都有其局限性,不够灵活; 另外由于前面几种方法内部也是通过ThreadPoolExecutor方式实现,使用ThreadPoolExecutor有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险。
代码演示:
public static void main(String[] args) { //创建定长线程池,指定线程池最大线程数为4 // ExecutorService executorService = Executors.newFixedThreadPool(4); //创建带缓存的线程池,线程池线程数由任务数决定 // ExecutorService executorService = Executors.newCachedThreadPool(); //创建一个单线程线程池 // ExecutorService executorService=Executors.newSingleThreadExecutor(); //创建一个支持定时、周期任务的线程池 ExecutorService executorService = Executors.newScheduledThreadPool(8); //定义任务 Runnable task = new Runnable() { //定义票的总量100张 private int ticket = 100; @Override public void run() { while (true) { if (ticket == 0) { break; } System.out.println(Thread.currentThread().getName() + "售出第" + ticket + "张票"); ticket--; } } }; //提交任务。这里提交4次代表创建4个线程去执行任务 for (int i = 0; i < 4; i++) { executorService.submit(task); } //关闭线程池 executorService.shutdown();//当线程池中的任务全部执行完毕后,才会执行关闭操作 executorService.shutdownNow();//立即关闭线程池,可能会造成任务执行异常 }

浙公网安备 33010602011771号