为什么使用线程池及线程池讲解

来源:互联网 发布:linux 机器重启时间 编辑:程序博客网 时间:2024/06/08 19:15

当我们需要频繁的创建多个线程进行耗时操作时,每次通过new Thread实现并不是一个好的方式,每次new Thred新建和销毁对象性能较差,线程缺乏管理,并不能充分利用每一个线程,可能无限制新建线程,相互之间竞争,可能占用过多系统资源导致死锁,并且缺乏定时执行、定期执行、线程中断等功能。

java提供了四种线程池,他能够有效的管理、调度线程,避免过多的资源消耗。线程池的有点有以下几点:

1)重用存在的线程,减少对象创建销毁的开销。

2)可有效的控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。

3)提供定时执行、定期执行、单线程、并发数控制等功能。

线程池都实现了ExecutorService接口,该接口定义了线程池需要实现的接口,如submit、execute、shutdown等。它的实现由ThreadPoolExecutor和ScheduledThreadPoolExecutor,ThreadPoolExecutor也就是我们运用最多的线程池实现,ScheduledThreadPoolExecutor则用于周期性的执行任务。同常我们并不会直接new的形式创建线程池,因为创建参数过程相对复杂,我们通常通过Executors工厂类来简化这个过程。

public class Executors {    /**     * Creates a thread pool that reuses a fixed number of threads     * operating off a shared unbounded queue.  At any point, at most     * <tt>nThreads</tt> threads will be active processing tasks.     * If additional tasks are submitted when all threads are active,     * they will wait in the queue until a thread is available.     * If any thread terminates due to a failure during execution     * prior to shutdown, a new one will take its place if needed to     * execute subsequent tasks.  The threads in the pool will exist     * until it is explicitly {@link ExecutorService#shutdown shutdown}.     *     * @param nThreads the number of threads in the pool     * @return the newly created thread pool     * @throws IllegalArgumentException if <tt>nThreads <= 0</tt>     */    public static ExecutorService newFixedThreadPool(int nThreads) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>());    }    /**     * Creates a thread pool that reuses a fixed number of threads     * operating off a shared unbounded queue, using the provided     * ThreadFactory to create new threads when needed.  At any point,     * at most <tt>nThreads</tt> threads will be active processing     * tasks.  If additional tasks are submitted when all threads are     * active, they will wait in the queue until a thread is     * available.  If any thread terminates due to a failure during     * execution prior to shutdown, a new one will take its place if     * needed to execute subsequent tasks.  The threads in the pool will     * exist until it is explicitly {@link ExecutorService#shutdown     * shutdown}.     *     * @param nThreads the number of threads in the pool     * @param threadFactory the factory to use when creating new threads     * @return the newly created thread pool     * @throws NullPointerException if threadFactory is null     * @throws IllegalArgumentException if <tt>nThreads <= 0</tt>     */    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>(),                                      threadFactory);    }    /**     * Creates an Executor that uses a single worker thread operating     * off an unbounded queue. (Note however that if this single     * thread terminates due to a failure during execution prior to     * shutdown, a new one will take its place if needed to execute     * subsequent tasks.)  Tasks are guaranteed to execute     * sequentially, and no more than one task will be active at any     * given time. Unlike the otherwise equivalent     * <tt>newFixedThreadPool(1)</tt> the returned executor is     * guaranteed not to be reconfigurable to use additional threads.     *     * @return the newly created single-threaded Executor     */    public static ExecutorService newSingleThreadExecutor() {        return new FinalizableDelegatedExecutorService            (new ThreadPoolExecutor(1, 1,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue<Runnable>()));    }    /**     * Creates an Executor that uses a single worker thread operating     * off an unbounded queue, and uses the provided ThreadFactory to     * create a new thread when needed. Unlike the otherwise     * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the     * returned executor is guaranteed not to be reconfigurable to use     * additional threads.     *     * @param threadFactory the factory to use when creating new     * threads     *     * @return the newly created single-threaded Executor     * @throws NullPointerException if threadFactory is null     */    public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {        return new FinalizableDelegatedExecutorService            (new ThreadPoolExecutor(1, 1,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue<Runnable>(),                                    threadFactory));    }    /**     * 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 <tt>execute</tt> 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.     *     * @return the newly created thread pool     */    public static ExecutorService newCachedThreadPool() {        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                      60L, TimeUnit.SECONDS,                                      new SynchronousQueue<Runnable>());    }    /**     * Creates a thread pool that creates new threads as needed, but     * will reuse previously constructed threads when they are     * available, and uses the provided     * ThreadFactory to create new threads when needed.     * @param threadFactory the factory to use when creating new threads     * @return the newly created thread pool     * @throws NullPointerException if threadFactory is null     */    public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                      60L, TimeUnit.SECONDS,                                      new SynchronousQueue<Runnable>(),                                      threadFactory);    }    /**     * Creates a single-threaded executor that can schedule commands     * to run after a given delay, or to execute periodically.     * (Note however that if this single     * thread terminates due to a failure during execution prior to     * shutdown, a new one will take its place if needed to execute     * subsequent tasks.)  Tasks are guaranteed to execute     * sequentially, and no more than one task will be active at any     * given time. Unlike the otherwise equivalent     * <tt>newScheduledThreadPool(1)</tt> the returned executor is     * guaranteed not to be reconfigurable to use additional threads.     * @return the newly created scheduled executor     */    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {        return new DelegatedScheduledExecutorService            (new ScheduledThreadPoolExecutor(1));    }    /**     * Creates a single-threaded executor that can schedule commands     * to run after a given delay, or to execute periodically.  (Note     * however that if this single thread terminates due to a failure     * during execution prior to shutdown, a new one will take its     * place if needed to execute subsequent tasks.)  Tasks are     * guaranteed to execute sequentially, and no more than one task     * will be active at any given time. Unlike the otherwise     * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt>     * the returned executor is guaranteed not to be reconfigurable to     * use additional threads.     * @param threadFactory the factory to use when creating new     * threads     * @return a newly created scheduled executor     * @throws NullPointerException if threadFactory is null     */    public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {        return new DelegatedScheduledExecutorService            (new ScheduledThreadPoolExecutor(1, threadFactory));    }    /**     * Creates a thread pool that can schedule commands to run after a     * given delay, or to execute periodically.     * @param corePoolSize the number of threads to keep in the pool,     * even if they are idle.     * @return a newly created scheduled thread pool     * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt>     */    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {        return new ScheduledThreadPoolExecutor(corePoolSize);    }    /**     * Creates a thread pool that can schedule commands to run after a     * given delay, or to execute periodically.     * @param corePoolSize the number of threads to keep in the pool,     * even if they are idle.     * @param threadFactory the factory to use when the executor     * creates a new thread.     * @return a newly created scheduled thread pool     * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt>     * @throws NullPointerException if threadFactory is null     */    public static ScheduledExecutorService newScheduledThreadPool(            int corePoolSize, ThreadFactory threadFactory) {        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);    }    /**     * Returns an object that delegates all defined {@link     * ExecutorService} methods to the given executor, but not any     * other methods that might otherwise be accessible using     * casts. This provides a way to safely "freeze" configuration and     * disallow tuning of a given concrete implementation.     * @param executor the underlying implementation     * @return an <tt>ExecutorService</tt> instance     * @throws NullPointerException if executor null     */    public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {        if (executor == null)            throw new NullPointerException();        return new DelegatedExecutorService(executor);    }    /**     * Returns an object that delegates all defined {@link     * ScheduledExecutorService} methods to the given executor, but     * not any other methods that might otherwise be accessible using     * casts. This provides a way to safely "freeze" configuration and     * disallow tuning of a given concrete implementation.     * @param executor the underlying implementation     * @return a <tt>ScheduledExecutorService</tt> instance     * @throws NullPointerException if executor null     */    public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {        if (executor == null)            throw new NullPointerException();        return new DelegatedScheduledExecutorService(executor);    }    /**     * Returns a default thread factory used to create new threads.     * This factory creates all new threads used by an Executor in the     * same {@link ThreadGroup}. If there is a {@link     * java.lang.SecurityManager}, it uses the group of {@link     * System#getSecurityManager}, else the group of the thread     * invoking this <tt>defaultThreadFactory</tt> method. Each new     * thread is created as a non-daemon thread with priority set to     * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum     * priority permitted in the thread group.  New threads have names     * accessible via {@link Thread#getName} of     * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence     * number of this factory, and <em>M</em> is the sequence number     * of the thread created by this factory.     * @return a thread factory     */    public static ThreadFactory defaultThreadFactory() {        return new DefaultThreadFactory();    }    /**     * Returns a thread factory used to create new threads that     * have the same permissions as the current thread.     * This factory creates threads with the same settings as {@link     * Executors#defaultThreadFactory}, additionally setting the     * AccessControlContext and contextClassLoader of new threads to     * be the same as the thread invoking this     * <tt>privilegedThreadFactory</tt> method.  A new     * <tt>privilegedThreadFactory</tt> can be created within an     * {@link AccessController#doPrivileged} action setting the     * current thread's access control context to create threads with     * the selected permission settings holding within that action.     *     * <p> Note that while tasks running within such threads will have     * the same access control and class loader settings as the     * current thread, they need not have the same {@link     * java.lang.ThreadLocal} or {@link     * java.lang.InheritableThreadLocal} values. If necessary,     * particular values of thread locals can be set or reset before     * any task runs in {@link ThreadPoolExecutor} subclasses using     * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is     * necessary to initialize worker threads to have the same     * InheritableThreadLocal settings as some other designated     * thread, you can create a custom ThreadFactory in which that     * thread waits for and services requests to create others that     * will inherit its values.     *     * @return a thread factory     * @throws AccessControlException if the current access control     * context does not have permission to both get and set context     * class loader.     */    public static ThreadFactory privilegedThreadFactory() {        return new PrivilegedThreadFactory();    }    /**     * Returns a {@link Callable} object that, when     * called, runs the given task and returns the given result.  This     * can be useful when applying methods requiring a     * <tt>Callable</tt> to an otherwise resultless action.     * @param task the task to run     * @param result the result to return     * @return a callable object     * @throws NullPointerException if task null     */    public static <T> Callable<T> callable(Runnable task, T result) {        if (task == null)            throw new NullPointerException();        return new RunnableAdapter<T>(task, result);    }    /**     * Returns a {@link Callable} object that, when     * called, runs the given task and returns <tt>null</tt>.     * @param task the task to run     * @return a callable object     * @throws NullPointerException if task null     */    public static Callable<Object> callable(Runnable task) {        if (task == null)            throw new NullPointerException();        return new RunnableAdapter<Object>(task, null);    }    /**     * Returns a {@link Callable} object that, when     * called, runs the given privileged action and returns its result.     * @param action the privileged action to run     * @return a callable object     * @throws NullPointerException if action null     */    public static Callable<Object> callable(final PrivilegedAction<?> action) {        if (action == null)            throw new NullPointerException();        return new Callable<Object>() {    public Object call() { return action.run(); }};    }    /**     * Returns a {@link Callable} object that, when     * called, runs the given privileged exception action and returns     * its result.     * @param action the privileged exception action to run     * @return a callable object     * @throws NullPointerException if action null     */    public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {        if (action == null)            throw new NullPointerException();return new Callable<Object>() {    public Object call() throws Exception { return action.run(); }};    }    /**     * Returns a {@link Callable} object that will, when     * called, execute the given <tt>callable</tt> under the current     * access control context. This method should normally be     * invoked within an {@link AccessController#doPrivileged} action     * to create callables that will, if possible, execute under the     * selected permission settings holding within that action; or if     * not possible, throw an associated {@link     * AccessControlException}.     * @param callable the underlying task     * @return a callable object     * @throws NullPointerException if callable null     *     */    public static <T> Callable<T> privilegedCallable(Callable<T> callable) {        if (callable == null)            throw new NullPointerException();        return new PrivilegedCallable<T>(callable);    }    /**     * Returns a {@link Callable} object that will, when     * called, execute the given <tt>callable</tt> under the current     * access control context, with the current context class loader     * as the context class loader. This method should normally be     * invoked within an {@link AccessController#doPrivileged} action     * to create callables that will, if possible, execute under the     * selected permission settings holding within that action; or if     * not possible, throw an associated {@link     * AccessControlException}.     * @param callable the underlying task     *     * @return a callable object     * @throws NullPointerException if callable null     * @throws AccessControlException if the current access control     * context does not have permission to both set and get context     * class loader.     */    public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {        if (callable == null)            throw new NullPointerException();        return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);    }    // Non-public classes supporting the public methods    /**     * A callable that runs given task and returns given result     */    static final class RunnableAdapter<T> implements Callable<T> {        final Runnable task;        final T result;        RunnableAdapter(Runnable  task, T result) {            this.task = task;            this.result = result;        }        public T call() {            task.run();            return result;        }    }    /**     * A callable that runs under established access control settings     */    static final class PrivilegedCallable<T> implements Callable<T> {        private final AccessControlContext acc;        private final Callable<T> task;        private T result;        private Exception exception;        PrivilegedCallable(Callable<T> task) {            this.task = task;            this.acc = AccessController.getContext();        }        public T call() throws Exception {            AccessController.doPrivileged(new PrivilegedAction<T>() {                    public T run() {                        try {                            result = task.call();                        } catch (Exception ex) {                            exception = ex;                        }                        return null;                    }                }, acc);            if (exception != null)                throw exception;            else                return result;        }    }    /**     * A callable that runs under established access control settings and     * current ClassLoader     */    static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {        private final ClassLoader ccl;        private final AccessControlContext acc;        private final Callable<T> task;        private T result;        private Exception exception;        PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {            this.task = task;            this.ccl = Thread.currentThread().getContextClassLoader();            this.acc = AccessController.getContext();            acc.checkPermission(new RuntimePermission("getContextClassLoader"));            acc.checkPermission(new RuntimePermission("setContextClassLoader"));        }        public T call() throws Exception {            AccessController.doPrivileged(new PrivilegedAction<T>() {                    public T run() {                        ClassLoader savedcl = null;                        Thread t = Thread.currentThread();                        try {                            ClassLoader cl = t.getContextClassLoader();                            if (ccl != cl) {                                t.setContextClassLoader(ccl);                                savedcl = cl;                            }                            result = task.call();                        } catch (Exception ex) {                            exception = ex;                        } finally {                            if (savedcl != null)                                t.setContextClassLoader(savedcl);                        }                        return null;                    }                }, acc);            if (exception != null)                throw exception;            else                return result;        }    }    /**     * The default thread factory     */    static class DefaultThreadFactory implements ThreadFactory {        static final AtomicInteger poolNumber = new AtomicInteger(1);        final ThreadGroup group;        final AtomicInteger threadNumber = new AtomicInteger(1);        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;        }    }    /**     *  Thread factory capturing access control and class loader     */    static class PrivilegedThreadFactory extends DefaultThreadFactory {        private final ClassLoader ccl;        private final AccessControlContext acc;        PrivilegedThreadFactory() {            super();            this.ccl = Thread.currentThread().getContextClassLoader();            this.acc = AccessController.getContext();            acc.checkPermission(new RuntimePermission("setContextClassLoader"));        }        public Thread newThread(final Runnable r) {            return super.newThread(new Runnable() {                public void run() {                    AccessController.doPrivileged(new PrivilegedAction<Object>() {                        public Object run() {                            Thread.currentThread().setContextClassLoader(ccl);                            r.run();                            return null;                        }                    }, acc);                }            });        }    }    /**     * A wrapper class that exposes only the ExecutorService methods     * of an ExecutorService implementation.     */    static class DelegatedExecutorService extends AbstractExecutorService {        private final ExecutorService e;        DelegatedExecutorService(ExecutorService executor) { e = executor; }        public void execute(Runnable command) { e.execute(command); }        public void shutdown() { e.shutdown(); }        public List<Runnable> shutdownNow() { return e.shutdownNow(); }        public boolean isShutdown() { return e.isShutdown(); }        public boolean isTerminated() { return e.isTerminated(); }        public boolean awaitTermination(long timeout, TimeUnit unit)            throws InterruptedException {            return e.awaitTermination(timeout, unit);        }        public Future<?> submit(Runnable task) {            return e.submit(task);        }        public <T> Future<T> submit(Callable<T> task) {            return e.submit(task);        }        public <T> Future<T> submit(Runnable task, T result) {            return e.submit(task, result);        }        public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)            throws InterruptedException {            return e.invokeAll(tasks);        }        public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,                                             long timeout, TimeUnit unit)            throws InterruptedException {            return e.invokeAll(tasks, timeout, unit);        }        public <T> T invokeAny(Collection<? extends Callable<T>> tasks)            throws InterruptedException, ExecutionException {            return e.invokeAny(tasks);        }        public <T> T invokeAny(Collection<? extends Callable<T>> tasks,                               long timeout, TimeUnit unit)            throws InterruptedException, ExecutionException, TimeoutException {            return e.invokeAny(tasks, timeout, unit);        }    }    static class FinalizableDelegatedExecutorServiceextends DelegatedExecutorService {FinalizableDelegatedExecutorService(ExecutorService executor) {    super(executor);}protected void finalize()  {    super.shutdown();}    }    /**     * A wrapper class that exposes only the ScheduledExecutorService     * methods of a ScheduledExecutorService implementation.     */    static class DelegatedScheduledExecutorService            extends DelegatedExecutorService            implements ScheduledExecutorService {        private final ScheduledExecutorService e;        DelegatedScheduledExecutorService(ScheduledExecutorService executor) {            super(executor);            e = executor;        }        public ScheduledFuture<?> schedule(Runnable command, long delay,  TimeUnit unit) {            return e.schedule(command, delay, unit);        }        public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {            return e.schedule(callable, delay, unit);        }        public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay,  long period, TimeUnit unit) {            return e.scheduleAtFixedRate(command, initialDelay, period, unit);        }        public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,  long delay, TimeUnit unit) {            return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);        }    }    /** Cannot instantiate. */    private Executors() {}}

启动指定数量的线程---------ThreadPoolExecutor

  ThreadPoolExecutor是线程池的实现之一,他的功能是启动指定数量的线程以及将任务添加到一个队列中,并且将任务分发给空闲线程。ExecutorService的生命周期包括三种状态:运行、关闭、终止。创建后便进入运行状态,当调用了shutdown()方法时便进入关闭状态,此时意味着ExecutorService不再接受新的任务,但它还在执行已经提交了得任务。当所有已经提交了得任务完成后,就变成终止状态。

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize

long keepAliveTime

TimeUnit unit

BlockingQueue<Runnable> workQueue

ThreadFactory threadFactory

RejectedExecutionHandler handler)


参数说明:

corePoolSize:线程池中所保存的核心线程数。线程池启动后默认是空的,只有任务来临时才会创建线程以处理请求。prestarAllCoreThreads方法可以在线程池启动后即启动所有核心线程以等待任务。

maximumPoolSize:线程池允许创建的最大线程数。当workQueue使用无界队列时(如LinkBlockingQueue),则此参数无效。它与corePoolSize的作用是调整“线程池中实际运行的线程的数量”。例如,当新任务提交给线程池时,如果线程池中运行的线程数量小于corePoolSize,则创建新线城来处理请求;如果此时线程池中运行的线程数量大于corePoolSize但是却小于maximumPoolSize,则仅当阻塞队列(workQueue)满时才创建新线程。如果设置的corePoolSize等于maximumPoolSize则创建了固定大小的线程池。如果将maximumPoolSize设置为基本的无界值(如Integer.MAX_VALUE),则允许线程池适应任意数量的并发任务。

keepAliveTime:当前线程池线程总数大于核心线程时,终止多余的空闲线程的时间

Unit :keepAliveTime的时间单位,可选分、毫秒、秒

workQueue:任务队列,如果当前线程达到核心线程数,且当前所有线程都处于活跃状态时,将新加入的任务放入此队列

threadFactory:线程工厂,让用户可以定制线程的创建过程,通常不需要设置

Handler:拒绝策略,当线程池与workQueue队列都满了的情况下,对新加任务采取的处理策略


其中的workQueue有下列几个常用实现。

1)ArrayBlockingQueue:基于数组结构的有界队列,此队列按FIFO(先进先出)原则对任务进行排序。如果此队列满了还有任务进来,则调用拒绝策略。

2)LinkedBlockingQueue:基于链表结构的无界队列,此队列按FIFO原则对任务进行排序。因为他是无界的,根本不会满,所以采用此队列后线程池将忽略拒绝策略(handler)参数,同时还将忽略最大线程数maximumPoolSize参数

3)SynchronousQueue:直接将任务提交給线程而不是将他加入到队列,实际上此队列是空的。每个插入的操作必须等到另一个调用移除的操作;如果新任务来了线程池没有任何可用线程处理的话则调用拒绝策略。其实要是把maximumPoolSize设置成无界的,加上此队列,就等同于Executors.newCachedThreadPool()。

4)PriorityBlockingQueue:具有优先级的有界队列,可以自定义优先级,默认是按自然排序。


当线程池和workQueue队列都满了的情况下,对新加任务采取的处理策略的默认实现。

1)AbortPolicy:拒绝任务,抛出RejectedExecutionException异常。线程池的默认策略。

2)CallRunsPolicy:拒绝新任务被加入,如果该线程池好没有被关闭,那么将这个新任务执行在调用线程中

3)DiscardOldestPolicy:如果执行程序尚未被关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果失败,重复此过程)。这样的结果是最后加入的任务反而有可能被执行,先加入的都被删除了。

4)DiscardPolicy:加不进的任务都被抛弃了,同时没有异常抛出


定时执行一些任务——————ScheduledThreadPoolExecutor

在某些情况下,我们可能需要定时执行一些任务,此时可以通过ScheduledThreadPoolExecutor来实现。我们只需要通过Executoes的newScheduledThreadPool函数即可创建定时执行任务的线程池。


在具有N个处理器的机器上,线程池具有N或N+1个线程时一般会会获得最大cpu利用率

原创粉丝点击