精华内容
下载资源
问答
  • 手动创建线程池

    2019-12-16 09:53:31
    ScheduledExecutorService executorService = ...以上代码阿里的代码规范插件会提示手动创建线程池,用以下方式创建线程池 ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("--...
    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(100);

    以上代码阿里的代码规范插件会提示手动创建线程池,用以下方式创建线程池

    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("---thread-%d").build();
    int size = 50;
    ExecutorService executorService = new ThreadPoolExecutor(size,size,0L,TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(),namedThreadFactory);

     

    展开全文
  • 用ThreadPoolExecutor手动创建线程池

    万次阅读 2020-04-04 18:30:59
    用ThreadPoolExecutor手动创建线程池 首先我们看一下ThreadPoolExecutor的构造方法 public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小 int maximumPoolSize, // 最大线程池大小 lon...

    用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;
    }
    

    我们这里就通过这构造方法的七个参数来创建一个ThreadPoolExecutor对象

    ExecutorService threadPool = new ThreadPoolExecutor(
        2,
        5,
        3,
        TimeUnit.SECONDS,
        new LinkedBlockingDeque<>(3),
        Executors.defaultThreadFactory(),
        new ThreadPoolExecutor.AbortPolicy());
    

    我们这里创建的线程默认开启2个线程,最大可开启5个线程,当线程开启后3秒没被使用就会关闭该线程,允许3个用户进入LinkedBlockingDeque阻塞队列等待,用了Executors对象提供的默认线程创建工厂,AbortPolicy表示拒绝任务的处理程序。

    线程工厂

    我们这里来看一下Executors默认的线程创建工厂,这里用了静态内部类实现了ThreadFactory接口

    static class DefaultThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;
    
        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
            Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                poolNumber.getAndIncrement() +
                "-thread-";
        }
    
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }
    

    我们这里可以看到Executors的DefaultThreadFactory提供了一个无参的构造方法,当我们不想自己实现ThreadFactory接口的时候可以直接调用Executors的DefaultThreadFactory类,当然我们可以看到其实ThreadFactory也有许多的实现类,我们这里就不一一赘述了,有兴趣的小伙伴也可以自己写ThreadFactory接口的实现类

    拒绝策略

    在这里插入图片描述

    我们可以看到RejectedExecutionHandler接口的四个实现类,都在ThreadPoolExecutor中

    我们这里分别来看下

    AbortPolicy
    public static class AbortPolicy implements RejectedExecutionHandler {
        /**
             * Creates an {@code AbortPolicy}.
             */
        public AbortPolicy() { }
    
        /**
             * Always throws RejectedExecutionException.
             *
             * @param r the runnable task requested to be executed
             * @param e the executor attempting to execute this task
             * @throws RejectedExecutionException always
             */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }
    

    超出最大承载会抛出RejectedExecutionException异常

    最大承载: Deque + max

    CallerRunsPolicy
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() { }
    
        /**
         * Executes task r in the caller's thread, unless the executor
         * has been shut down, in which case the task is discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }
    

    如果超载了,被什么线程调用的就会回到该线程取执行方法

    DiscardOldestPolicy
    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        /**
             * Creates a {@code DiscardOldestPolicy} for the given executor.
             */
        public DiscardOldestPolicy() { }
    
        /**
             * Obtains and ignores the next task that the executor
             * would otherwise execute, if one is immediately available,
             * and then retries execution of task r, unless the executor
             * is shut down, in which case task r is instead discarded.
             *
             * @param r the runnable task requested to be executed
             * @param e the executor attempting to execute this task
             */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }
    

    队列满了,尝试和最早的竞争,也不会抛出异常

    DiscardPolicy
    public static class DiscardPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardPolicy}.
         */
        public DiscardPolicy() { }
    
        /**
         * Does nothing, which has the effect of discarding task r.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }
    

    队列满了,丢掉任务,不会抛出异常

    展开全文
  • 线程池由浅入深-手动创建线程池

    千次阅读 2018-07-23 22:26:56
     JDK提供了一个ThreadPoolExecutor类供我们来手动创建线程池,类定义如下: public class ThreadPoolExecutor extends AbstractExecutorService 1. 构造方法  想要通过ThreadPoolExecutor类来创建线程池,...

     JDK提供了一个ThreadPoolExecutor类供我们来手动创建线程池,类定义如下:

    public class ThreadPoolExecutor extends AbstractExecutorService
    
    

    1. 构造方法

     想要通过ThreadPoolExecutor类来创建线程池,实质上就是向其构造方法传入不同参数来获取不同的线程池。

     看具体的构造方法之前,我们先看一下其中会涉及到的参数:

    参数名含义
    corePoolSize线程池维护线程的最少数量。线程池至少会保持该数量的线程存在,即使没有任务可以处理。(注意:这里说的至少是指线程达到这个数量后,即使有空闲的线程也不会释放,而不是说线程池创建好之后就会初始化这么多线程)
    maximumPoolSize线程池最大数量,线程池允许创建的最大线程数,如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程来执行任务。值得注意的是,线程池队列如果使用的是无界队列,那么这个参数就没有什么效果
    uint线程活动保持时间的单位,可选择的时间有时分秒等,即线程池维护线程所允许的空闲时间的单位,和keepAliveTime配合使用
    keepAliveTime线程活动保持时间,线程池的工作线程空闲后,保持存活的时间,所以,当任务很多的时候,并且每个任务执行的时间比较短,可以调大时间,即调大线程活动保持时间,可以提高线程的利用率
    workQueue任务队列,用于暂时保存任务的工作队列
    threadFactory用于创建线程的工厂
    handler饱和策略

     构造方法如下:

    • 使用给定的参数,工作队列,饱和策略以及工厂方法来创建线程池,这是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;
        }
    
    • 使用给定的参数,工作队列,默认的饱和策略和工厂方法来创建线程池。
    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
        }
    
    • 使用给定的参数,工作队列,工厂方法,默认的饱和策略来创建线程池。
    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 threadFactory, defaultHandler);
        }
    
    • 使用给定的参数,工作队列,饱和策略,默认的工厂方法来创建线程池。
    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  RejectedExecutionHandler handler) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), handler);
        }
    

    2. 工作队列

     在线程池中,一般使用一个队列进行任务和线程池中线程进行耦合,工作队列有如下几种:

    • ArrayBlockingQueue:

     基于数组结构的有界阻塞队列,此队列按照FIFO(先进先出)原则对元素进行排序。

    • LinkedBlockingQueue:

     基于链表结构的有界阻塞队列,也按照FIFO排序元素,吞吐量高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool(n)使用了此队列。

    • PriorityBlockingQueue:

     具有优先级的无限阻塞队列,即优先队列。

    • SynchronousQueue:

     一个不存储元素的阻塞队列。每个插入操作必须等待另一个线程调用移除操作,否则插入操作一直处于阻塞状态,可以视为只有一个元素的队列。吞吐量要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool()使用了此队列。

    3. 饱和策略

     饱和策略又称拒绝策略,指的是当线程池中每个线程都在承载线程任务时,这时如果又有了新的线程任务,线程池将会采用的策略,常见线程策略如下:

    • AbortPolicy:

     该策略是线程池的默认策略。使用该策略时,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常。

    • CallerRunsPolicy:只用调用这所在的线程来运行任务

     线程池队列满了,会直接丢弃新加入的任务并且不会抛出异常。

    • DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务

     如果队列满了,会将最早进入队列的线程任务退出,再尝试将新的任务加入队列。

    • DiscardPolicy:

     当线程池使用此策略,如果添加到线程池失败(线程池满时),那么主线程将会自己去执行该任务,不会等待线程池中的线程去执行。

    • 自定义

     JDK允许我们自定义饱和策略,只要实现RejectedExecutionHandler接口,并且实现rejectedExecution方法就可以了,rejectedExecution方法中定义饱和策略的逻辑代码。

    4. 手动创建线程池

     接下来,使用 ThreadPoolExecutor类进行线程池的创建。

    public class MyThreadPool {
    
        /**
         * 基本参数
         */
        static int corePoolSize = 10;
    
        static int maximumPoolSizeSize = 100;
    
        static long keepAliveTime = 1;
    
        static ArrayBlockingQueue workQueue = new ArrayBlockingQueue(10);
    
    
        public static void main(String[] args) {
            
            // 使用默认饱和策略创建线程池
            ThreadPoolExecutor executor = new ThreadPoolExecutor(
                    corePoolSize,
                    maximumPoolSizeSize,
                    keepAliveTime,
                    TimeUnit.SECONDS,
                    workQueue,
                    // JDK1.8后此方法作废
                    new ThreadFactoryBuilder().setNameFormat("XX-task-%d").build());
            // 向线程池中添加任务
            executor.execute(() -> System.out.println("ok"));
        }
    }
    
    展开全文
  • 手动创建线程池以及线程拒绝策略

    万次阅读 2019-10-14 20:31:16
    由于之前说使用Exectors类创建线程池时候,会造成OOM,建议手动创建线程池。 今天就尝试手动创建线程池,并且介绍它的4中拒绝策略和手动写拒绝策略。 在创建线程池之前,我们先看看线程池创建的构造函数和各个字段...

    由于之前说使用Exectors类创建线程池时候,会造成OOM,建议手动创建线程池。

    今天就尝试手动创建线程池,并且介绍它的4中拒绝策略和手动写拒绝策略。

    在创建线程池之前,我们先看看线程池创建的构造函数和各个字段的意义。

     

    corePoolSize:核心线程数,当线程数未达到核心线程时,新的任务会创建新的线程,即使有线程空闲也会创建新的线程。
    maximumPoolSize:线程最大数,当阻塞队列满了之后,就会创建新的线程,达到最大线程数为止。
    keepAliveTime:线程空闲时间,当线程空闲时间超过此值,并且线程数大于核心线程,此线程将被回收,以此来保证核心线程数量。
    unit:线程空余时间单位。
    workQueue:阻塞队列,当任务大于线程数,阻塞队列还未满,就会加入阻塞队列中
    threadFactory:管理创建的线程,可以设置线程的名称等属性。
    handler:拒绝策略,当阻塞对面已满,线程达到最大线程,就会采用阻塞策略。

    知道了各个参数的意义,现在来手动创建线程池。

    先创建一个任务,再创建一个线程池。

    package test.thread.pool;
    
    public class Task implements Runnable {
    
        private int i;
    
        public Task(int i) {
            this.i = i;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " print " + i);
        }
    
    }
    
    package test.thread.pool;
    
    import java.util.concurrent.*;
    
    public class CreateThreadPool {
    
        public static void main(String[] args) {
            BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(2);
    
            ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4,
                    60, TimeUnit.SECONDS, blockingQueue,
                    Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
            for (int i = 0; i < 10; i++) {
                Task task = new Task(i);
                executor.execute(task);
            }
            executor.shutdown();
        }
    
    }
    

    我们创建了一个核心线程数为2个,最大线程数为4,线程空闲时间为60s,阻塞队列大小为2的线程池,阻塞策略为默认的

    AbortPolicy 根据源码可以看到,此种拒绝策略直接抛出rejectedExecution异常,执行结果如下。

    pool-1-thread-1 print 0
    Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task test.thread.pool.Task@6d6f6e28 rejected from java.util.concurrent.ThreadPoolExecutor@135fbaa4[Running, pool size = 4, active threads = 3, queued tasks = 0, completed tasks = 2]
    pool-1-thread-2 print 1
    	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
    pool-1-thread-4 print 5
    	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
    pool-1-thread-1 print 2
    	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
    pool-1-thread-3 print 4
    	at test.thread.pool.CreateThreadPool.main(CreateThreadPool.java:15)
    pool-1-thread-4 print 3
    DiscardPolicy 拒绝策略,这种策略是不会做任何处理,不会抛出异常,直接丢弃任务,运行结果如下

    import java.util.concurrent.*;
    
    public class CreateThreadPool {
    
        public static void main(String[] args) {
            BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(2);
    
            ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4,
                    60, TimeUnit.SECONDS, blockingQueue,
                    Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());
            for (int i = 0; i < 10; i++) {
                Task task = new Task(i);
                executor.execute(task);
            }
            executor.shutdown();
        }
    
    }

     

    运行结果如下,可以看到没有抛出异常,不做任何处理,直接丢弃了后面的任务。

    pool-1-thread-2 print 1
    pool-1-thread-3 print 4
    pool-1-thread-2 print 2
    pool-1-thread-4 print 5
    pool-1-thread-1 print 0
    pool-1-thread-3 print 3
    
    Process finished with exit code 0
    DiscardOldestPolicy 拒绝策略是从队列中移除老的任务,继续执行任务。

     

    由运行结果可以看到,前面2,3,6,7任务被丢弃了。

    pool-1-thread-1 print 0
    pool-1-thread-2 print 1
    pool-1-thread-2 print 9
    pool-1-thread-1 print 8
    pool-1-thread-3 print 4
    pool-1-thread-4 print 5
    
    Process finished with exit code 0
    
    CallerRunsPolicy 是不会丢弃任务,直接运行任务的run方法,即使用主线程执行任务,执行结果如下。

     

    根据运行结果可以看到,其中有main线程执行任务,因为当线程不足时,会由主线程直接执行run方法。

    main print 6
    pool-1-thread-4 print 5
    pool-1-thread-2 print 1
    pool-1-thread-2 print 3
    pool-1-thread-1 print 0
    pool-1-thread-3 print 4
    pool-1-thread-4 print 2
    main print 7
    pool-1-thread-2 print 8
    pool-1-thread-1 print 9
    
    Process finished with exit code 0

     

    以上就是线程池的4种拒绝策略,但是并不是很好,还是建议大家手动创建拒绝策略,下面给大家提供一种拒绝策略,供大家参考,当线程拒绝时,还是重复向队列中加,加进去继续让线程处理,执行结果如下。

    package test.thread.pool;
    
    import java.util.concurrent.*;
    
    public class CreateThreadPool {
    
        public static void main(String[] args) {
            BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(2);
    
            ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4,
                    60, TimeUnit.SECONDS, blockingQueue,
                    Executors.defaultThreadFactory(), new RejectedExecutionHandler() {
                @Override
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                    if (!executor.isShutdown()) {
                        try {
                            executor.getQueue().put(r);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            for (int i = 0; i < 10; i++) {
                Task task = new Task(i);
                executor.execute(task);
            }
            executor.shutdown();
        }
    
    }
    

     

    运行结果可以看到,任务都被执行,并且没有使用主线程运行。

    pool-1-thread-1 print 0
    pool-1-thread-4 print 5
    pool-1-thread-3 print 4
    pool-1-thread-2 print 1
    pool-1-thread-1 print 2
    pool-1-thread-4 print 3
    pool-1-thread-1 print 8
    pool-1-thread-3 print 6
    pool-1-thread-2 print 7
    pool-1-thread-4 print 9
    
    Process finished with exit code 0

     

    最后再贴上更改线程名称等属性的代码

    package test.thread.pool;
    
    import java.util.concurrent.*;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class CreateThreadPool {
    
        static class NameThreadFactory implements ThreadFactory {
    
            private AtomicInteger count = new AtomicInteger();
            private String name;
    
            public NameThreadFactory(String name) {
                this.name = name + "-";
            }
    
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r, name + count.incrementAndGet());
                if (t.isDaemon()) {
                    t.setDaemon(false);
                }
                if (t.getPriority() != Thread.NORM_PRIORITY) {
                    t.setPriority(Thread.NORM_PRIORITY);
                }
                return t;
            }
        }
    
        public static void main(String[] args) {
            BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(2);
    
            ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4,
                    60, TimeUnit.SECONDS, blockingQueue,
                    new CreateThreadPool.NameThreadFactory("test-thread-pool"), new RejectedExecutionHandler() {
                @Override
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                    if (!executor.isShutdown()) {
                        try {
                            executor.getQueue().put(r);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            for (int i = 0; i < 10; i++) {
                Task task = new Task(i);
                executor.execute(task);
            }
            executor.shutdown();
        }
    
    }
    

     

    运行结果如下,可以看到线程名称变化

    test-thread-pool-1 print 0
    test-thread-pool-2 print 1
    test-thread-pool-2 print 3
    test-thread-pool-1 print 2
    test-thread-pool-2 print 6
    test-thread-pool-1 print 7
    test-thread-pool-2 print 8
    test-thread-pool-1 print 9
    test-thread-pool-3 print 4
    test-thread-pool-4 print 5
    
    Process finished with exit code 0

    以上就是手动创建线程,以及创建线程策略和线程属性的例子,如有不对的地方,还请指出,谢谢

    展开全文
  • 阿里代码规约:手动创建线程池,效果会更好哦

    万次阅读 多人点赞 2019-08-30 21:54:43
    规避资源耗尽的风险,高并发下推荐手动创建线程池
  • 一、为什么要手动创建线程池? 我们之所以要手动创建线程池,是因为 JDK 自带的工具类所创建的线程池存在一定的弊端,那究竟存在怎么样的弊端呢?首先来回顾一下 JDK 中线程池框架的继承关系: JDK 线程池框架继承...
  • 一、为什么要手动创建线程池? 我们之所以要手动创建线程池,是因为 JDK 自带的工具类所创建的线程池存在一定的弊端,那究竟存在怎么样的弊端呢?首先来回顾一下 JDK 中线程池框架的继承关系: JDK 线程池框架继承...
  • 今天创建了线程池,创建时候阿里巴巴提示我: 手动创建线程池,效果会更好哦。我也没在意。果然就遭到了报应,内存泄漏了… 本来我是这样创建的: ExecutorService executorService = Executors.newFixedThreadPool...
  • 今天在回顾线程池的创建时,使用Executors创建线程池报错了,出现了以下问题:手动创建线程池,效果会更好哦。 查阅了阿里巴巴Java开发手册 回顾一下,通过ThreadPoolExecutor来创建。 找一下源码 public ...
  • 不使用 Executors 工厂类创建, 推荐手动创建线程池
  • 手动创建线程池 阿里巴巴手册中有一句话 规避资源耗尽的风险,推荐写法: //获取系统处理器个数,作为线程池数量 int nThreads = Runtime.getRuntime().availableProcessors(); ThreadFactory ...
  • 1. 手动创建线程池ThreadPoolExecutor // ThreadPoolExecutor构造函数源码 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ...
  • 使用阿里规约扫描代码发现很多不符合规范之处,所以在有优化代码的...手动创建线程池:https://www.jianshu.com/p/c0f8d1e2b4eb Java8中使用lambda表达式:https://blog.csdn.net/bitcarmanlee/article/details/70...
  • Java 手动创建线程池

    万次阅读 2018-03-28 11:38:30
    使用给定的参数和默认的饱和策略、默认的工厂方法创建线程池 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&amp;lt;Runna...
  • Java基础: 手动创建线程池

    千次阅读 2020-08-17 12:02:16
    使用ExecutorServices直接创建线程池的缺点: 1. FixedThreadPool或者SingleThreadPool 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。 2.CachedThreadPool 允许的创建线程数量...
  • 结果一算,311万得花费5.7个小时,太慢了,于是就看了同事之前写的多线程,拷贝过来发现我的阿里编码规约提示:手动创建线程池,效果会更好哦 解决过程 参考博客 我之前通篇看过阿里编码规约,这块说到了我才有印象。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,933
精华内容 15,173
关键字:

手动创建线程池