zoukankan      html  css  js  c++  java
  • 线程池框架Executor创建线程池

    以上成员均在java.util.concurrent包中,是JDK并发包的核心类。其中ThreadPoolExecutor表示一个线程池。Executors类则扮演着线程池工厂的角色,通过Executors可以取得一个拥有特定功能的线程池。从UML图中亦可知,ThreadPoolExecutor类实现了Executor接口,因此通过这个接口,任何Runnable的对象都可以被ThreadPoolExecutor线程池调度。 

     newFixedThreadPool()方法:该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。

    newSingleThreadExecutor()方法:该方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。

    newCachedThreadPool()方法:该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。

    newSingleThreadScheduledExecutor()方法:该方法返回一个ScheduledExecutorService对象,线程池大小为1。ScheduledExecutorService接口在ExecutorService接口之上扩展了在给定时间执行某任务的功能,如在某个固定的延时之后执行,或者周期性执行某个任务。

    newScheduledThreadPool()方法:该方法也返回一个ScheduledExecutorService对象,但该线程池可以指定线程数量。

    public class ThreadPoolDemo {
        public static class MyTask implements  Runnable{
    
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis()+"Thread ID:"+Thread.currentThread().getId());
                try {
                    Thread.sleep(1000);
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
            }
    
            public static void main(String[] args) {
                MyTask task = new MyTask();
                ExecutorService es = Executors.newFixedThreadPool(3);
                for (int i = 0; i<10; i++){
                    es.submit(task);
                }
            }
        }
    }

     

     每一秒执行3个。

    换成newCachedThreadPool,会一下子执行完毕。

    /**
     * Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available.  These pools will typically improve the performance
     * of programs that execute many short-lived asynchronous tasks.
     * Calls to {@code execute} will reuse previously constructed
     * threads if available. If no existing thread is available, a new
     * thread will be created and added to the pool. Threads that have
     * not been used for sixty seconds are terminated and removed from
     * the cache. Thus, a pool that remains idle for long enough will
     * not consume any resources. Note that pools with similar
     * properties but different details (for example, timeout parameters)
     * may be created using {@link ThreadPoolExecutor} constructors.

    对应的翻译

    创建一个线程池,根据需要创建新线程,但是

    *将重用之前构建的线程

    *可用。这些池通常会提高性能

    执行许多短期的异步任务的程序。

    *调用{@code execute}将重用之前构造的

    *线程(如果可用)。如果没有可用的线程,则使用新线程

    *线程将被创建并添加到池中。线程,

    *未使用60秒将终止并删除

    *缓存。因此,一个足够长时间保持空闲的池将会

    *不消耗任何资源。注意,有类似的池

    *属性,但不同的细节(例如,超时参数)

    *可以使用{@link ThreadPoolExecutor}构造函数创建。

     newScheduledThreadPool(),它返回一个ScheduledExecutorService对象,可以根据时间需要对线程进行调度。

    而scheduleAtFixedRate和scheduleWithFixedDelay,它们的任务都开始于给定的初始延时,不同之处在于后期任务,前者按给定的周期,后者是按给定的 延时。

    public class ScheduledExecutorServiceDemo {
        public static void main(String[] args) {
            ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
            ses.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    try{
                        Thread.sleep(1000);
                        System.out.println(System.currentTimeMillis()/1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },0,2, TimeUnit.SECONDS);
        }
    
    }
    

    若改变Thread.sleep(5)的时间大于执行周期时间,那么执行周期时间就会变成大的那个时间,比如sleep(5),而执行周期是2秒。那么运行结果的执行周期也会变成5秒。

    上面的核心线程池(比如 newFixedThreadPool(),newCachedThreadPool())的内部都实现ThreadPoolExecutor

    其源码:

      public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
        }

    corePoolSize:指定了线程池中的线程数量。
    maximumPoolSize:指定了线程池中的最大线程数量。
    keepAliveTime:当线程池线程数量超过corePoolSize时,多余的空闲线程的存活时间。即,超过corePoolSize的空闲线程,在多长时间内,会被销毁。
    unit:keepAliveTime的单位。
    workQueue:任务队列,被提交但尚未被执行的任务。
    threadFactory:线程工厂,用于创建线程,一般用默认的即可。
    handler:拒绝策略。当任务太多来不及处理,如何拒绝任务。

    不经一番彻骨寒,哪有梅花扑鼻香?
  • 相关阅读:
    6章-项目进度管理-day5
    常规正则表达式
    axios删除接口
    elk
    英语笔记
    升级打怪
    用computed实现watch的保持子组件与父组件值同步
    vertical-align不生效的问题
    css居右
    使用maven创建spring工程出现配置文件打不开/不存在的错误
  • 原文地址:https://www.cnblogs.com/zongyao/p/13831095.html
Copyright © 2011-2022 走看看