threadpoolexcutor是一款线程池组件,threadpooltaskexecutor线程池使用

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: