threadpoolexcutor是一款线程池组件,threadpooltaskexecutor线程池使用
线程池主要解决两个问题:一是在执行大量异步任务时,线程池可以提供更好的性能。不使用线程池时,每当需要执行一个异步任务时,就直接创建一个新的线程来运行,线程的创建和销毁都是代价高昂的。线程池中的线程是可重用的,因此没有必要在每次执行异步任务时重新创建和销毁线程。第二,线程池提供了一种资源限制和管理手段,比如限制线程数量,动态添加新线程。每个ThreadPoolExecutor还保存一些基本的统计数据,比如当前线程池完成的任务数。
我们先来看类图。
Excecutor是一个工具类,它提供了许多静态方法,根据用户的选择返回不同的线程池实例。ThreadPool继承AbstractExecutorService。
让我们看一下源代码,
private final atomic integer CTL=new atomic integer(ctlOf(RUNNING,0));私有静态final int COUNT_BITS=Integer。尺码-3;私有静态最终int容量=(1 COUNT _ BITS)-1;//runState存储在高位bitsprivate静态final int RUNNING=-1 COUNT _ BITS;私有静态最终int SHUTDOWN=0 COUNT _ BITS私有静态最终int STOP=1 COUNT _ BITS私有静态final int整理=2 COUNT _ BITS私有静态final int TERMINATED=3 COUNT _ BITS;成员ctl是一个整数原子变量,用于记录当前线程池状态和线程池中的线程数。这有点类似于ReentrantReadWriteLock使用一个变量来存储两种信息。
线程池中有五种状态3360。
正在运行:可以接受新任务并处理阻塞队列中的任务。关闭:拒绝接受新任务,但处理阻塞队列中的任务。停止:拒绝新任务并放弃阻塞队列中的任务。整理:执行完所有任务(包括阻塞队列中的任务)后,当前线程池中的活动线程数为0,终止的方法将被调用。终止:终止状态。终止的方法调用完成后的状态。
线程池状态转换如下:
运行-SHUTDOWN:显示调用SHUTDOWN方法,或者在finalize()方法中隐式调用shutdown()方法。RUNNINGSHUTDOWN-STOP:显示调用关闭方法shut down-整理:STOP-线程池和任务队列为空时整理:线程池为空时整理-终止:终止()hook方法完成
线程池的使用
合理使用线程池可以带来三个好处:
减少资源消耗。为了减少创建和销毁线程的数量,每个工作线程都可以重用,并且可以执行多个任务。提高响应速度。当任务到达时,可以在不必要地创建线程后立即执行任务。提高线程的可管理性。根据系统的承受能力,可以调整线程池中工作线线程的数量,防止服务器因内存消耗过大而耗尽(每个线程需要1MB左右的内存,打开的线程越多,消耗的内存越多,最后崩溃)。在java.util.concurrent.Executors线程工厂类中,提供了一些静态工厂来生成一些公共线程池。官方建议使用Executors工程类来创建线程池对象。Executors类中有一个线程池创建方法,如下所示:
公共静态执行器服务NewFixedThreadPool (intnth Reads):返回线程池对象。(创建有界线程池,即可以指定池中的最大线程数。)获得了一个线程池ExecutorService对象,那么如何使用呢?这里,使用线程池对象的方法定义如下:
大众未来?Submit (runnable task) 3360在线程池中获取一个线程对象,执行Future接口:用来记录线程任务执行后产生的结果。
要在线程池中使用线程对象:
创建一个线程池对象。创建一个可运行的接口子类对象。(任务)提交Runnable接口子类对象。(take task)关闭线程池(一般不做)。可运行的实现类代码:
>public class MyRunnable implements Runnable { @Override public void run() { System.out.println("我要一个教练"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("教练来了: " + Thread.currentThread().getName()); System.out.println("教我游泳,交完后,教练回到了游泳池"); }}public class ThreadPoolDemo { public static void main(String[] args) { // 创建线程池对象 ExecutorService service = Executors.newFixedThreadPool(2);//包含2个线程对象 // 创建Runnable实例对象 MyRunnable r = new MyRunnable(); //自己创建线程对象的方式 // Thread t = new Thread(r); // t.start(); ---> 调用MyRunnable中的run() // 从线程池中获取线程对象,然后调用MyRunnable中的run() service.submit(r); // 再获取个线程对象,调用MyRunnable中的run() service.submit(r); service.submit(r); // 注意:submit方法调用结束后,程序并不终止,是因为线程池控制了线程的关闭。 // 将使用完的线程又归还到了线程池中 // 关闭线程池 //service.shutdown(); }}Callable测试代码:
<T> Future<T> submit(Callable<T> task) : 获取线程池中的某一个线程对象,并执行.Future : 表示计算的结果.
V get() : 获取计算完成的结果。
public class ThreadPoolDemo2 { public static void main(String[] args) throws Exception { // 创建线程池对象 ExecutorService service = Executors.newFixedThreadPool(2);//包含2个线程对象 // 创建Runnable实例对象 Callable<Double> c = new Callable<Double>() { @Override public Double call() throws Exception { return Math.random(); } }; // 从线程池中获取线程对象,然后调用Callable中的call() Future<Double> f1 = service.submit(c); // Futur 调用get() 获取运算结果 System.out.println(f1.get()); Future<Double> f2 = service.submit(c); System.out.println(f2.get()); Future<Double> f3 = service.submit(c); System.out.println(f3.get()); }}
线程池的练习
public class Demo04 { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService pool = Executors.newFixedThreadPool(3); SumCallable sc = new SumCallable(100); Future<Integer> fu = pool.submit(sc); Integer integer = fu.get(); System.out.println("结果: " + integer); SumCallable sc2 = new SumCallable(200); Future<Integer> fu2 = pool.submit(sc2); Integer integer2 = fu2.get(); System.out.println("结果: " + integer2); pool.shutdown(); }}
public class SumCallable implements Callable<Integer> { private int n; public SumCallable(int n) { this.n = n; } @Override public Integer call() throws Exception { // 求1-n的和? int sum = 0; for (int i = 1; i <= n; i++) { sum += i; } return sum; }}
到此这篇关于Java并发包线程池ThreadPoolExecutor的实现的文章就介绍到这了,更多相关Java并发包线程池ThreadPoolExecutor内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。