精华内容
下载资源
问答
  • executors
    2018-03-28 11:39:48

    ThreadPoolExecutor的构造函数:

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

    CachedThreadPool:

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

    FixedThreadPool:

    public static ExecutorService newFixedThreadPool(int nThreads){
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory tf){
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      tf);
    }
    更多相关内容
  • 主要介绍了Azkaban报错-azkaban.executor.ExecutorManagerException: No active executors found,本文给大家介绍的非常详细,需要的朋友可以参考下
  • 【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors返回的线程池对象的弊端如下: 1) ...
  • 主要介绍了Java并发编程中使用Executors类创建和管理线程的用法,文中举了用其启动线程和设置线程优先级的例子,需要的朋友可以参考下
  • 主要介绍了java 中Executor, ExecutorService 和 Executors 间的不同的相关资料,需要的朋友可以参考下
  • Executors 框架

    2022-01-12 21:41:59
    Executors 框架,是一个根据一组执行策略调用、调度、执行和控制的异步任务的框架。 不使用线程池,创建线程数量不加控制或控制不当,会导致应用程序内存溢出。所以,创建线程池是一个很好的解决方案。它可以限制...

    Executors 框架,是一个根据一组执行策略调用、调度、执行和控制的异步任务的框架。

    不使用线程池,创建线程数量不加控制或控制不当,会导致应用程序内存溢出。所以,创建线程池是一个很好的解决方案。它可以限制核心线程数量,还可以回收再利用使用结束的线程。利用Executors 框架可以非常方便的创建一个线程池。

    Executors类源码如下:

    package java.util.concurrent;
    
    import java.lang.Thread.UncaughtExceptionHandler;
    import java.security.AccessControlContext;
    import java.security.AccessController;
    import java.security.PrivilegedAction;
    import java.security.PrivilegedActionException;
    import java.security.PrivilegedExceptionAction;
    import java.util.Collection;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    import sun.security.util.SecurityConstants;
    
    public class Executors {
        public static ExecutorService newFixedThreadPool(int var0) {
            return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
        }
    
        public static ExecutorService newWorkStealingPool(int var0) {
            return new ForkJoinPool(var0, ForkJoinPool.defaultForkJoinWorkerThreadFactory, (UncaughtExceptionHandler)null, true);
        }
    
        public static ExecutorService newWorkStealingPool() {
            return new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, (UncaughtExceptionHandler)null, true);
        }
    
        public static ExecutorService newFixedThreadPool(int var0, ThreadFactory var1) {
            return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var1);
        }
    
        public static ExecutorService newSingleThreadExecutor() {
            return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
        }
    
        public static ExecutorService newSingleThreadExecutor(ThreadFactory var0) {
            return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var0));
        }
    
        public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
        }
    
        public static ExecutorService newCachedThreadPool(ThreadFactory var0) {
            return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue(), var0);
        }
    
        public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
            return new Executors.DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));
        }
    
        public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory var0) {
            return new Executors.DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1, var0));
        }
    
        public static ScheduledExecutorService newScheduledThreadPool(int var0) {
            return new ScheduledThreadPoolExecutor(var0);
        }
    
        public static ScheduledExecutorService newScheduledThreadPool(int var0, ThreadFactory var1) {
            return new ScheduledThreadPoolExecutor(var0, var1);
        }
    
        public static ExecutorService unconfigurableExecutorService(ExecutorService var0) {
            if (var0 == null) {
                throw new NullPointerException();
            } else {
                return new Executors.DelegatedExecutorService(var0);
            }
        }
    
        public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService var0) {
            if (var0 == null) {
                throw new NullPointerException();
            } else {
                return new Executors.DelegatedScheduledExecutorService(var0);
            }
        }
    
        public static ThreadFactory defaultThreadFactory() {
            return new Executors.DefaultThreadFactory();
        }
    
        public static ThreadFactory privilegedThreadFactory() {
            return new Executors.PrivilegedThreadFactory();
        }
    
        public static <T> Callable<T> callable(Runnable var0, T var1) {
            if (var0 == null) {
                throw new NullPointerException();
            } else {
                return new Executors.RunnableAdapter(var0, var1);
            }
        }
    
        public static Callable<Object> callable(Runnable var0) {
            if (var0 == null) {
                throw new NullPointerException();
            } else {
                return new Executors.RunnableAdapter(var0, (Object)null);
            }
        }
    
        public static Callable<Object> callable(final PrivilegedAction<?> var0) {
            if (var0 == null) {
                throw new NullPointerException();
            } else {
                return new Callable<Object>() {
                    public Object call() {
                        return var0.run();
                    }
                };
            }
        }
    
        public static Callable<Object> callable(final PrivilegedExceptionAction<?> var0) {
            if (var0 == null) {
                throw new NullPointerException();
            } else {
                return new Callable<Object>() {
                    public Object call() throws Exception {
                        return var0.run();
                    }
                };
            }
        }
    
        public static <T> Callable<T> privilegedCallable(Callable<T> var0) {
            if (var0 == null) {
                throw new NullPointerException();
            } else {
                return new Executors.PrivilegedCallable(var0);
            }
        }
    
        public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> var0) {
            if (var0 == null) {
                throw new NullPointerException();
            } else {
                return new Executors.PrivilegedCallableUsingCurrentClassLoader(var0);
            }
        }
    
        private Executors() {
        }
    
        static class DelegatedScheduledExecutorService extends Executors.DelegatedExecutorService implements ScheduledExecutorService {
            private final ScheduledExecutorService e;
    
            DelegatedScheduledExecutorService(ScheduledExecutorService var1) {
                super(var1);
                this.e = var1;
            }
    
            public ScheduledFuture<?> schedule(Runnable var1, long var2, TimeUnit var4) {
                return this.e.schedule(var1, var2, var4);
            }
    
            public <V> ScheduledFuture<V> schedule(Callable<V> var1, long var2, TimeUnit var4) {
                return this.e.schedule(var1, var2, var4);
            }
    
            public ScheduledFuture<?> scheduleAtFixedRate(Runnable var1, long var2, long var4, TimeUnit var6) {
                return this.e.scheduleAtFixedRate(var1, var2, var4, var6);
            }
    
            public ScheduledFuture<?> scheduleWithFixedDelay(Runnable var1, long var2, long var4, TimeUnit var6) {
                return this.e.scheduleWithFixedDelay(var1, var2, var4, var6);
            }
        }
    
        static class FinalizableDelegatedExecutorService extends Executors.DelegatedExecutorService {
            FinalizableDelegatedExecutorService(ExecutorService var1) {
                super(var1);
            }
    
            protected void finalize() {
                super.shutdown();
            }
        }
    
        static class DelegatedExecutorService extends AbstractExecutorService {
            private final ExecutorService e;
    
            DelegatedExecutorService(ExecutorService var1) {
                this.e = var1;
            }
    
            public void execute(Runnable var1) {
                this.e.execute(var1);
            }
    
            public void shutdown() {
                this.e.shutdown();
            }
    
            public List<Runnable> shutdownNow() {
                return this.e.shutdownNow();
            }
    
            public boolean isShutdown() {
                return this.e.isShutdown();
            }
    
            public boolean isTerminated() {
                return this.e.isTerminated();
            }
    
            public boolean awaitTermination(long var1, TimeUnit var3) throws InterruptedException {
                return this.e.awaitTermination(var1, var3);
            }
    
            public Future<?> submit(Runnable var1) {
                return this.e.submit(var1);
            }
    
            public <T> Future<T> submit(Callable<T> var1) {
                return this.e.submit(var1);
            }
    
            public <T> Future<T> submit(Runnable var1, T var2) {
                return this.e.submit(var1, var2);
            }
    
            public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> var1) throws InterruptedException {
                return this.e.invokeAll(var1);
            }
    
            public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> var1, long var2, TimeUnit var4) throws InterruptedException {
                return this.e.invokeAll(var1, var2, var4);
            }
    
            public <T> T invokeAny(Collection<? extends Callable<T>> var1) throws InterruptedException, ExecutionException {
                return this.e.invokeAny(var1);
            }
    
            public <T> T invokeAny(Collection<? extends Callable<T>> var1, long var2, TimeUnit var4) throws InterruptedException, ExecutionException, TimeoutException {
                return this.e.invokeAny(var1, var2, var4);
            }
        }
    
        static class PrivilegedThreadFactory extends Executors.DefaultThreadFactory {
            private final AccessControlContext acc;
            private final ClassLoader ccl;
    
            PrivilegedThreadFactory() {
                SecurityManager var1 = System.getSecurityManager();
                if (var1 != null) {
                    var1.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
                    var1.checkPermission(new RuntimePermission("setContextClassLoader"));
                }
    
                this.acc = AccessController.getContext();
                this.ccl = Thread.currentThread().getContextClassLoader();
            }
    
            public Thread newThread(final Runnable var1) {
                return super.newThread(new Runnable() {
                    public void run() {
                        AccessController.doPrivileged(new PrivilegedAction<Void>() {
                            public Void run() {
                                Thread.currentThread().setContextClassLoader(PrivilegedThreadFactory.this.ccl);
                                var1.run();
                                return null;
                            }
                        }, PrivilegedThreadFactory.this.acc);
                    }
                });
            }
        }
    
        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 var1 = System.getSecurityManager();
                this.group = var1 != null ? var1.getThreadGroup() : Thread.currentThread().getThreadGroup();
                this.namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
            }
    
            public Thread newThread(Runnable var1) {
                Thread var2 = new Thread(this.group, var1, this.namePrefix + this.threadNumber.getAndIncrement(), 0L);
                if (var2.isDaemon()) {
                    var2.setDaemon(false);
                }
    
                if (var2.getPriority() != 5) {
                    var2.setPriority(5);
                }
    
                return var2;
            }
        }
    
        static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
            private final Callable<T> task;
            private final AccessControlContext acc;
            private final ClassLoader ccl;
    
            PrivilegedCallableUsingCurrentClassLoader(Callable<T> var1) {
                SecurityManager var2 = System.getSecurityManager();
                if (var2 != null) {
                    var2.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
                    var2.checkPermission(new RuntimePermission("setContextClassLoader"));
                }
    
                this.task = var1;
                this.acc = AccessController.getContext();
                this.ccl = Thread.currentThread().getContextClassLoader();
            }
    
            public T call() throws Exception {
                try {
                    return AccessController.doPrivileged(new PrivilegedExceptionAction<T>() {
                        public T run() throws Exception {
                            Thread var1 = Thread.currentThread();
                            ClassLoader var2 = var1.getContextClassLoader();
                            if (PrivilegedCallableUsingCurrentClassLoader.this.ccl == var2) {
                                return PrivilegedCallableUsingCurrentClassLoader.this.task.call();
                            } else {
                                var1.setContextClassLoader(PrivilegedCallableUsingCurrentClassLoader.this.ccl);
    
                                Object var3;
                                try {
                                    var3 = PrivilegedCallableUsingCurrentClassLoader.this.task.call();
                                } finally {
                                    var1.setContextClassLoader(var2);
                                }
    
                                return var3;
                            }
                        }
                    }, this.acc);
                } catch (PrivilegedActionException var2) {
                    throw var2.getException();
                }
            }
        }
    
        static final class PrivilegedCallable<T> implements Callable<T> {
            private final Callable<T> task;
            private final AccessControlContext acc;
    
            PrivilegedCallable(Callable<T> var1) {
                this.task = var1;
                this.acc = AccessController.getContext();
            }
    
            public T call() throws Exception {
                try {
                    return AccessController.doPrivileged(new PrivilegedExceptionAction<T>() {
                        public T run() throws Exception {
                            return PrivilegedCallable.this.task.call();
                        }
                    }, this.acc);
                } catch (PrivilegedActionException var2) {
                    throw var2.getException();
                }
            }
        }
    
        static final class RunnableAdapter<T> implements Callable<T> {
            final Runnable task;
            final T result;
    
            RunnableAdapter(Runnable var1, T var2) {
                this.task = var1;
                this.result = var2;
            }
    
            public T call() {
                this.task.run();
                return this.result;
            }
        }
    }
    

    展开全文
  • Java中Executors类中几种创建各类型线程池方法及简单实例
  • 线程池—Executors 详解

    千次阅读 2021-03-05 11:09:15
    各位志同道合的朋友们大家好,我是一个一直在一线互联网踩坑十余年的编码爱好者,...ThreadPoolExecutor 和 Executors,上一节学习了 ThreadPoolExecutor 的使用方式,本节重点来看 Executors 是如何创建线程池的...

    各位志同道合的朋友们大家好,我是一个一直在一线互联网踩坑十余年的编码爱好者,现在将我们的各种经验以及架构实战分享出来,如果大家喜欢,就关注我,一起将技术学深学透,我会每一篇分享结束都会预告下一专题

    线程池的创建分为两种方式:ThreadPoolExecutor 和 Executors,上一节学习了 ThreadPoolExecutor 的使用方式,本节重点来看 Executors 是如何创建线程池的。Executors 可以创建以下六种线程池。FixedThreadPool(n):创建一个数量固定的线程池,超出的任务会在队列中等待空闲的线程,可用于控制程序的最大并发数。

    CachedThreadPool():短时间内处理大量工作的线程池,会根据任务数量产生对应的线程,并试图缓存线程以便重复使用,如果限制 60 秒没被使用,则会被移除缓存。

    SingleThreadExecutor():创建一个单线程线程池。

    ScheduledThreadPool(n):创建一个数量固定的线程池,支持执行定时性或周期性任务。

    SingleThreadScheduledExecutor():此线程池就是单线程的 newScheduledThreadPool。

    WorkStealingPool(n):Java 8 新增创建线程池的方法,创建时如果不设置任何参数,则以当前机器处理器个数作为线程个数,此线程池会并行处理任务,不能保证执行顺序。

    下面分别来看以上六种线程池的具体代码使用。

    FixedThreadPool 使用

    创建固定个数的线程池,具体示例如下:

    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);

    for (int i = 0; i < 3; i++) {

    fixedThreadPool.execute(() -> {

    System.out.println("CurrentTime - " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    });

    }

    以上程序执行结果如下:CurrentTime - 2019-06-27 20:58:58

    CurrentTime - 2019-06-27 20:58:58

    CurrentTime - 2019-06-27 20:58:59

    根据执行结果可以看出,newFixedThreadPool(2) 确实是创建了两个线程,在执行了一轮(2 次)之后,停了一秒,有了空闲线程,才执行第三次。

    CachedThreadPool 使用

    根据实际需要自动创建带缓存功能的线程池,具体代码如下:

    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

    for (int i = 0; i < 10; i++) {

    cachedThreadPool.execute(() -> {

    System.out.println("CurrentTime - " +

    LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    });

    }

    以上程序执行结果如下:CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    CurrentTime - 2019-06-27 21:24:46

    根据执行结果可以看出,newCachedThreadPool 在短时间内会创建多个线程来处理对应的任务,并试图把它们进行缓存以便重复使用。

    SingleThreadExecutor 使用

    创建单个线程的线程池,具体代码如下:

    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    for (int i = 0; i < 3; i++) {

    singleThreadExecutor.execute(() -> {

    System.out.println("CurrentTime - " +

    LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    });

    }

    以上程序执行结果如下:CurrentTime - 2019-06-27 21:43:34

    CurrentTime - 2019-06-27 21:43:35

    CurrentTime - 2019-06-27 21:43:36

    ScheduledThreadPool 使用

    创建一个可以执行周期性任务的线程池,具体代码如下:

    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);

    scheduledThreadPool.schedule(() -> {

    System.out.println("ThreadPool:" + LocalDateTime.now());

    }, 1L, TimeUnit.SECONDS);

    System.out.println("CurrentTime:" + LocalDateTime.now());

    以上程序执行结果如下:CurrentTime:2019-06-27T21:54:21.881

    ThreadPool:2019-06-27T21:54:22.845

    根据执行结果可以看出,我们设置的 1 秒后执行的任务生效了。

    SingleThreadScheduledExecutor 使用

    创建一个可以执行周期性任务的单线程池,具体代码如下:

    ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();

    singleThreadScheduledExecutor.schedule(() -> {

    System.out.println("ThreadPool:" + LocalDateTime.now());

    }, 1L, TimeUnit.SECONDS);

    System.out.println("CurrentTime:" + LocalDateTime.now());

    WorkStealingPool 使用

    Java 8 新增的创建线程池的方式,可根据当前电脑 CPU 处理器数量生成相应个数的线程池,使用代码如下:

    ExecutorService workStealingPool = Executors.newWorkStealingPool();

    for (int i = 0; i < 5; i++) {

    int finalNumber = i;

    workStealingPool.execute(() -> {

    System.out.println("I:" + finalNumber);

    });

    }

    Thread.sleep(5000);

    以上程序执行结果如下:I:0

    I:3

    I:2

    I:1

    I:4

    根据执行结果可以看出,newWorkStealingPool 是并行处理任务的,并不能保证执行顺序。

    ThreadPoolExecutor VS Executors

    ThreadPoolExecutor 和 Executors 都是用来创建线程池的,其中 ThreadPoolExecutor 创建线程池的方式相对传统,而 Executors 提供了更多的线程池类型(6 种),但很不幸的消息是在实际开发中并不推荐使用 Executors 的方式来创建线程池。

    无独有偶《阿里巴巴 Java 开发手册》中对于线程池的创建也是这样规定的,内容如下:线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的读者更加明确线程池的运行规则,规避资源耗尽的风险。

    说明:Executors 返回的线程池对象的弊端如下:

    1)FixedThreadPool 和 SingleThreadPool:

    允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

    2)CachedThreadPool 和 ScheduledThreadPool:

    允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

    OOM 是 OutOfMemoryError 的缩写,指内存溢出的意思。

    为什么不允许使用 Executors?

    我们先来看一个简单的例子:

    ExecutorService maxFixedThreadPool = Executors.newFixedThreadPool(10);

    for (int i = 0; i < Integer.MAX_VALUE; i++) {

    maxFixedThreadPool.execute(()->{

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    });

    }

    之后设置 JVM(Java 虚拟机)的启动参数: -Xmx10m -Xms10m (设置 JVM 最大运行内存等于 10M)运行程序,会抛出 OOM 异常,信息如下:Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

    at java.util.concurrent.LinkedBlockingQueue.offer(LinkedBlockingQueue.java:416)

    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1371)

    at xxx.main(xxx.java:127)

    为什么 Executors 会存在 OOM 的缺陷?

    通过以上代码,找到了 FixedThreadPool 的源码,代码如下:

    public static ExecutorService newFixedThreadPool(int nThreads) {

    return new ThreadPoolExecutor(nThreads, nThreads,

    0L, TimeUnit.MILLISECONDS,

    new LinkedBlockingQueue());

    }

    可以看到创建 FixedThreadPool 使用了 LinkedBlockingQueue 作为任务队列,继续查看 LinkedBlockingQueue 的源码就会发现问题的根源,源码如下:

    public LinkedBlockingQueue() {

    this(Integer.MAX_VALUE);

    }

    当使用 LinkedBlockingQueue 并没有给它指定长度的时候,默认长度为 Integer.MAX_VALUE,这样就会导致程序会给线程池队列添加超多个任务,因为任务量太大就有造成 OOM 的风险。

    相关面试题

    1.以下程序会输出什么结果?

    public static void main(String[] args) {

    ExecutorService workStealingPool = Executors.newWorkStealingPool();

    for (int i = 0; i < 5; i++) {

    int finalNumber = i;

    workStealingPool.execute(() -> {

    System.out.print(finalNumber);

    });

    }

    }

    A:不输出任何结果B:输出 0 到 9 有序数字C:输出 0 到 9 无需数字D:以上全对

    答:A题目解析:newWorkStealingPool 内部实现是 ForkJoinPool,它会随着主程序的退出而退出,因为主程序没有任何休眠和等待操作,程序会一闪而过,不会执行任何信息,所以也就不会输出任何结果。

    2.Executors 能创建单线程的线程池吗?怎么创建?

    答:Executors 可以创建单线程线程池,创建分为两种方式:Executors.newSingleThreadExecutor():创建一个单线程线程池。

    Executors.newSingleThreadScheduledExecutor():创建一个可以执行周期性任务的单线程池。

    3.Executors 中哪个线程适合执行短时间内大量任务?

    答:newCachedThreadPool() 适合处理大量短时间工作任务。它会试图缓存线程并重用,如果没有缓存任务就会新创建任务,如果线程的限制时间超过六十秒,则会被移除线程池,因此它比较适合短时间内处理大量任务。

    4.可以执行周期性任务的线程池都有哪些?

    答:可执行周期性任务的线程池有两个,分别是:newScheduledThreadPool() 和 newSingleThreadScheduledExecutor(),其中 newSingleThreadScheduledExecutor() 是 newScheduledThreadPool() 的单线程版本。

    5.JDK 8 新增了什么线程池?有什么特点?

    答:JDK 8 新增的线程池是 newWorkStealingPool(n),如果不指定并发数(也就是不指定 n),newWorkStealingPool() 会根据当前 CPU 处理器数量生成相应个数的线程池。它的特点是并行处理任务的,不能保证任务的执行顺序。

    6.newFixedThreadPool 和 ThreadPoolExecutor 有什么关系?

    答:newFixedThreadPool 是 ThreadPoolExecutor 包装,newFixedThreadPool 底层也是通过 ThreadPoolExecutor 实现的。

    newFixedThreadPool 的实现源码如下:

    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {

    return new ThreadPoolExecutor(nThreads, nThreads,

    0L, TimeUnit.MILLISECONDS,

    new LinkedBlockingQueue(),

    threadFactory);

    }

    7.单线程的线程池存在的意义是什么?

    答:单线程线程池提供了队列功能,如果有多个任务会排队执行,可以保证任务执行的顺序性。单线程线程池也可以重复利用已有线程,减低系统创建和销毁线程的性能开销。

    8.线程池为什么建议使用 ThreadPoolExecutor 创建,而非 Executors?

    答:使用 ThreadPoolExecutor 能让开发者更加明确线程池的运行规则,避免资源耗尽的风险。

    Executors 返回线程池的缺点如下:FixedThreadPool 和 SingleThreadPool 允许请求队列长度为 Integer.MAX_VALUE,可能会堆积大量请求,可能会导致内存溢出;

    CachedThreadPool 和 ScheduledThreadPool 允许创建线程数量为 Integer.MAX_VALUE,创建大量线程,可能会导致内存溢出。

    总结

    Executors 可以创建 6 种不同类型的线程池,其中 newFixedThreadPool() 适合执行单位时间内固定的任务数,newCachedThreadPool() 适合短时间内处理大量任务,newSingleThreadExecutor() 和 newSingleThreadScheduledExecutor() 为单线程线程池,而 newSingleThreadScheduledExecutor() 可以执行周期性的任务,是 newScheduledThreadPool(n) 的单线程版本,而 newWorkStealingPool() 为 JDK 8 新增的并发线程池,可以根据当前电脑的 CPU 处理数量生成对比数量的线程池,但它的执行为并发执行不能保证任务的执行顺序。

    下一篇:ThreadLocal详解在公众号菜单中可自行获取专属架构视频资料,包括不限于 java架构、python系列、人工智能系列、架构系列,以及最新面试、小程序、大前端均无私奉献,你会感谢我的哈

    往期精选

    展开全文
  • NULL 博文链接:https://bijian1013.iteye.com/blog/2284676
  • Executors: 是java.util.concurrent包下的一个类,提供了若干个静态方法,用于生成不同类型的线程池。Executors一共可以创建下面这四类线程池: 1.newFixedThreadPool创建一个可缓存线程池,如果线程池长度超过...
  • Executors快速创建线程以及管理线程池 文章目录 Executors快速创建线程以及管理线程池 简介 Executors方法介绍 1. newFixedThreadPool 2. newSingleThreadExecutor 3. newCachedThreadPool 4. ...

    Executors快速创建线程以及管理线程池



    简介

    • Executors类属于java.util.concurrent包;
    • 线程池的创建分为两种方式:ThreadPoolExecutor 和 Executors;
    • Executors(静态Executor工厂)用于创建线程池;
    • 工厂和工具方法Executor , ExecutorService , ScheduledExecutorService , ThreadFactory和Callable在此包中定义的类;

    Executors方法介绍

    • newFixedThreadPool(int nThreads) 数量固定的线程池
    • newSingleThreadExecutor() 单个线程的线程池
    • newCachedThreadPool() 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
    • newScheduledThreadPool(int corePoolSize) 周期性任务线程池
    • newWorkStealingPool(int parallelism) 多个线程共有一个阻塞队列,而newWorkStealingPool 中每一个线程都有一个自己的队列,当线程发现自己的队列没有任务了,就会到别的线程的队列里获取任务执行。可以简单理解为”窃取“。

    1. newFixedThreadPool

    • 数量固定的线程池
    public class ExecutorsDemo {
    
        public static void print() {
            System.out.println(Thread.currentThread().getName() + ":执行了");
        }
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(4);
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
        }
    }
    
    • 效果
      在这里插入图片描述

    2. newSingleThreadExecutor

    • 单个线程线程池
    public class ExecutorsDemo {
    
        public static void print() {
            System.out.println(Thread.currentThread().getName() + ":执行了");
        }
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newSingleThreadExecutor();
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
        }
    }
    
    • 效果
      在这里插入图片描述

    3. newCachedThreadPool

    • 可缓存线程池
    public class ExecutorsDemo {
    
        public static void print() {
            System.out.println(Thread.currentThread().getName() + ":执行了");
        }
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
            executorService.execute(() -> ExecutorsDemo.print());
        }
    }
    
    • 效果
      在这里插入图片描述

    4. newScheduledThreadPool

    • 执行定时性或周期性任务线程池
    • schedule 延迟任务
    • scheduleAtFixedRate 周期性任务,每1秒执行一次,不管当前任务是否结束
    • scheduleWithFixedDelay 周期性任务,直到任务停止后新的任务计时才开始
    public class ExecutorsDemo {
    
        public static void print(String msg) {
                System.out.println(Thread.currentThread().getName() + ":" + msg);
        }
    
        public static void main(String[] args) {
            ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(4);
            // 延迟5秒执行
            scheduled.schedule(() -> ExecutorsDemo.print("延迟任务"), 5000, TimeUnit.MILLISECONDS);
            // 周期性执行,首次延迟5秒,之后每1秒执行一次,不管当前任务是否结束
            scheduled.scheduleAtFixedRate(() -> ExecutorsDemo.print("周期性任务1"), 5000, 1000, TimeUnit.MILLISECONDS);
            // 周期性执行,首次延迟5秒,直到任务停止后新的任务计时才开始,1秒后执行
            scheduled.scheduleWithFixedDelay(() -> ExecutorsDemo.print("周期性任务2"), 5000, 1000, TimeUnit.MILLISECONDS);
        }
    }
    

    5. newWorkStealingPool

    • 任务窃取线程池
    public class ExecutorsDemo {
    
        public static void print(String msg) {
            System.out.println(Thread.currentThread().getName() + ":" + msg);
        }
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newWorkStealingPool(4);
            executorService.execute(() -> ExecutorsDemo.print("任务1"));
            executorService.execute(() -> ExecutorsDemo.print("任务2"));
            executorService.execute(() -> ExecutorsDemo.print("任务3"));
            executorService.execute(() -> ExecutorsDemo.print("任务4"));
            // 由于线程是抢占式,必须保持程序不终止,否则可能导致线程抢不到任务程序就终止了
            while (true) {}
        }
    }
    
    • 效果
      在这里插入图片描述
    展开全文
  • 线程池 Executors

    2021-09-09 20:39:38
    线程池 Executors
  • Executors四大线程池工厂方法的使用

    万次阅读 2020-10-15 15:19:17
    id: 1602583277163 title: 四大线程池的使用 ...Executors提供了四个创建线程池的工厂方法,分别是: Executors.newSingleThreadExecutor() Executors.newFixedThreadPool() Executors.newCachedThreadPool() E.
  • 但线程池维护的线程数并不是越多越好 需要我们合理的创建,使用线程池 因此 引出了 为什么不推荐使用 Executors 创建线程池 ** 2.0 Executors的四种线程池 概览 2.1 FixedThreadPool 定长线程池 2.1.1 创建一个...
  • 文章目录 线程池架构 newSingleThreadExecutor newFixedThreadPool newCachedThreadPool newScheduledThreadPool Executors和ThreaPoolExecutor创建线程池的区别 两种提交任务的方法 execute submit 线程池架构 上图...
  • 原文网址:线程池--Executors 简介 说明 线程池是Java多线程常用的技术, 常见线程池种类 种类 核心线程数 最大线程数 描述 固定大小(fixed) n ...
  • Executors如何创建线程池?

    千次阅读 2019-09-09 09:35:54
    Executors如何创建线程池? Executors 类是从 JDK 1.5 开始就新增的线程池创建的静态工厂类,它就是创建线程池的,但是很多的大厂已经不建议使用该类去创建线程池。原因在于,该类创建的很多线程池的内部使用了无界...
  • Executors和ThreadPoolExecutor详解

    千次阅读 2021-05-08 09:57:01
    而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool().
  • 这个学生答曰:使用jdk中自带的工厂类Executors 创建线程池!该学生回答完问题后,感觉面试官对此答案不是很满意,于是就跑回来问壹哥。那么接下来,壹哥就和大家来分享一下这道面试题的标准答案。 其实这个问题的...
  • java通过Executors可以创建五种方式的对线程: 第一种: 创建一个单线程。 第二种: 创建一个可变的多线程。: 第三种: 创建一个固定线程数的多线程。 第四种:创建一个定时的多线程。 第五种:创建可以调参数的多...
  • 一、使用Executors创建四种线程池: Executors类提供工厂方法用来创建不同类型的线程池,实际上Executors创建的四种线程底层的实现都是通过ThreadPoolExecutor实现的。 ExecutorService executorService = Executors...
  • Executors api详解

    2020-07-16 23:30:32
    今天时间学习Executors api,该类是JUC原子包中的类,通过单元测试代码把所有public api方法跑了一遍,大致了解了底层实现,初学乍练,有很多一知半解的地方,待后续有了深入理解再来补充 package test.java.util....
  • http://cuisuqiang.iteye.com/blog/2019372Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。...
  • 【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors返回的线程池对象的弊端如下: 1)...
  • 通过线程池复用线程有以下几点优点:根据返回的对象类型创建线程池可以分为三类:本文只讨论创建返回ThreadPoolExecutor对象在介绍Executors创建线程池方法前先介绍一下ThreadPoolExecutor,因为这些创建线程池的...
  • Executors详解

    千次阅读 2019-05-30 09:58:58
    这就是本文的全部,通过 Java 为我们提供的各种工具,可以方便的进行多任务的编程,通过使用 Executors、ExecutorService 以及 CompletionService 等工具类,我们可以创建复杂的并行任务执行算法,而且可以轻松改变...
  • Executors 6种线程池创建
  • 1、Executors.newFixedThreadPool 2、Executors.newSingleThreadExecutor 3、Executors.newCachedThreadPool 二、ScheduledThreadPoolExecutor运用 1、Executors.newScheduledThreadPool 2、Executors....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 168,696
精华内容 67,478
关键字:

executors