zoukankan      html  css  js  c++  java
  • Java多线程(十三):线程池

    线程池类结构


    1.Executor是顶级接口,有一个execute方法。
    2.ExecutorService接口提供了管理线程的方法。
    3.AbstractExecutorService管理普通线程,SchedulerExecutorService管理定时任务。

    简单的示例

    public class MyThread46 {
        public static void main(String[] args)
        {
            long startTime = System.currentTimeMillis();
            final List<Integer> l = new LinkedList<Integer>();
            ThreadPoolExecutor tp = new ThreadPoolExecutor(100, 100, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(20000));
            final Random random = new Random();
            for (int i = 0; i < 20000; i++)
            {
                tp.execute(new Runnable()
                {
                    public void run()
                    {
                        l.add(random.nextInt());
                    }
                });
            }
            tp.shutdown();
            try
            {
                tp.awaitTermination(1, TimeUnit.DAYS);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println(System.currentTimeMillis() - startTime);
            System.out.println(l.size());
        }
    }
    

    运行结果如下

    52
    19919
    

    ThreadPoolExecutor七个参数

    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler)
    

    1.corePoolSize
    线程池当前可以存在的线程数量
    2.maximumPoolSize
    线程池允许的最大线程数量
    3.keepAliveTime
    当线程数量比corePoolSize大时才会起作用,终止前的空余线程等待的最长时间。
    4.unit
    keepAliveTime的时间单位
    5.workQueue
    存储未被执行的任务
    6.threadFactory
    executor创建新线程时使用的工厂
    7.handler
    当执行被阻塞时使用handler

    corePoolSize与maximumPoolSize的关系

    1.池中线程数小于corePoolSize,新任务都不排队而是直接添加新线程。
    2.池中线程数大于等于corePoolSize,workQueue未满,将新任务加入workQueue而不是添加新线程。
    3.池中线程数大于等于corePoolSize,workQueue已满,但是线程数小于maximumPoolSize,添加新的线程来处理被添加的任务。
    4.池中线程数大于等于corePoolSize,workQueue已满,并且线程数大于等于maximumPoolSize,新任务被拒绝,使用handler处理被拒绝的任务。

    Executors

    1.newSingleThreadExecutos() 单线程线程池

        public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>(),
                                        threadFactory));
        }
    

    来新任务就排队,workQueue采用了无界队列LinkedBlockingQueue
    示例代码如下

    public class MyThread47{
        static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    
        public static void main(String[] args) {
            for(int i =0;i<10;i++) {
                final int index = i;
                singleThreadExecutor.execute(new Runnable() {
    
                    @Override
                    public void run() {
                        try {
                            System.out.println(index);
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            }
    
    }
    

    运行结果如下

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    

    2.newFixedThreadPool(int nThreads) 固定大小线程池

        public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }
    

    固定大小线程池和单线程线程池类似,可以手动指定线程数量
    示例代码如下

    public class MyThread48 {
        public static void main(String[] args) {
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
            for (int i = 0; i < 10; i++) {
                final int index = i;
    
                fixedThreadPool.execute(new Runnable() {
    
                    @Override
                    public void run() {
                        try {
                            System.out.println(index);
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    }
    

    运行结果如下

    0
    1
    2
    3
    4
    5
    6
    8
    7
    9
    

    3.newCachedThreadPool() 无界线程池

        public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
    

    有多少任务来直接执行,线程池最大数量Integer.MAX_VALUE,60s自动回收空闲线程。
    示例代码如下

    public class MyThread49 {
        public static void main(String[] args) {
            ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
            for (int i = 0; i < 10; i++) {
                final int index = i;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                cachedThreadPool.execute(new Runnable() {
    
                    @Override
                    public void run() {
                        System.out.println(index);
                    }
                });
            }
        }
    }
    

    运行结果如下

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
  • 相关阅读:
    激光打印机基于主机驱动程序、基于 PCL 驱动程序和 PostScript 驱动程序有何区别?
    转贴:打印机语言PostScript和PCL的比较
    编译器相关配置简介
    Graphics View的体系结构
    解决重装Qt后不能编译Examples的问题
    有符号数和无符号数的区别
    51单片机的外设
    AT89S52单片机P3口解惑
    双向端口设计
    AT89s52单片机的掉电测试
  • 原文地址:https://www.cnblogs.com/Java-Starter/p/11525301.html
Copyright © 2011-2022 走看看