• 线程池的创建


    如何创建线程池??

    阿里巴巴开发手册中写道,强制禁用使用Executors工具类来创建线程池,首先看一下Executors


    通过上述的几个方法可以创建线程池,在方法内部其实调用threadpool的构造方法来创建

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

    可以发现这几个方法内部都标明了Integer.MAX_VALUE,导致创建时可能会使线程池数量过多,以及允许请求队列的长度过大,造成堆空间堆积,造成OOM
    这也是禁止使用Executors创建线程池的原因

    所以推荐使用threadpoolExecutor的构造方法来创建线程池

    threadpoolExecutor分析

        public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) {
            if (corePoolSize < 0 ||
                maximumPoolSize <= 0 ||
                maximumPoolSize < corePoolSize ||
                keepAliveTime < 0)
                throw new IllegalArgumentException();
            if (workQueue == null || threadFactory == null || handler == null)
                throw new NullPointerException();
            this.acc = System.getSecurityManager() == null ?
                    null :
                    AccessController.getContext();
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }
    

    构造函数重要参数分析
    1.corepolsize 核心线程数定义了最小同时可以运行线程的数量
    2.maximumpoolSize 当队列中存放的任务达到队列容量时,当前可以用时运行的线程数量变为最大线程数
    3.workQueue 当新来一个任务时会判断当前运行的线程数是否达到核心线程数,如果达到,则放入队列中

    自定义线程池

    public class MyRunnable implements Runnable{
    
        public MyRunnable(int i) {
            this.i = i;
        }
    
        private int i;
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+ new Date() +i);
        }
    }
    
    public class MyThreadPool {
        private static final int corePoolSize = 5;
        private static final int maximumPoolSize = 10;
        private static final int workQueue = 100;
        private static final Long keepAliveTime = 1L;
        public static void main(String[] args) {
            ThreadPoolExecutor executor = new ThreadPoolExecutor(
                    corePoolSize,maximumPoolSize,keepAliveTime, TimeUnit.SECONDS,
                    new ArrayBlockingQueue<>(workQueue),
                    new ThreadPoolExecutor.CallerRunsPolicy());
    
            for (int i = 0; i < 10; i++) {
                MyRunnable runnable = new MyRunnable(i);
                executor.execute(runnable);
            }
            executor.shutdown();
            while (!executor.isTerminated()) {
            }
            System.out.println("finished");
        }
    }
    

    运行结果

  • 相关阅读:
    在应用程序中利用Jena API处理OWL本体
    Encoded vs Literal, RPC vs Document
    DWR、XMLHTTP、XMLRPC和Flex
    北京的第一场雪
    让IE浏览器提示下载或直接打开word文档
    色拉英语第一集第一幕:记得说“请”
    色拉英语第一集第三幕:凯文在家吗?
    30天敏捷结果(30):提升敏捷结果
    生活:兔年春节家庭寻宝习俗
    敏捷个人:2011/1/26聊天记录(沟通、优势)
  • 原文地址:https://www.cnblogs.com/qingfeng5438/p/13624216.html
Copyright © 2020-2023  润新知