Java: ThreadPoolExecutor parsing continued --Executors

Brief introduction

Eexecutor as a flexible and powerful asynchronous execution framework, which supports many different types of task execution strategy, provides a standard way to perform the task of the submission process and the development process of decoupling, based on producer - consumer model, submitted the task is equivalent to the producer thread, a thread to perform tasks equivalent to the consumer, and is represented by Runnable task, Executor's implementation also provides support for life-cycle, and statistics collection, management mechanism and application performance monitoring mechanisms.

Executors: it provides a series of static factory methods for creating a variety of thread pool

Executors: Create a worker thread by ThreadFactory

ThreadFactory

Interface ThreadFactory to produce a thread factory

public interface ThreadFactory {
    Thread newThread(Runnable r);
}

Implementation class

DefaultThreadFactory

    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();
            //线程Name前缀
            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;
        }
    }

PrivilegedThreadFactory

    //创建的新线程与当前线程具有相同的权限
    static class PrivilegedThreadFactory extends DefaultThreadFactory {
        private final AccessControlContext acc;
        private final ClassLoader ccl;

        PrivilegedThreadFactory() {
            super();
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                // Calls to getContextClassLoader from this class
                // never trigger a security check, but we check
                // whether our callers have this permission anyways.
                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);

                // Fail fast
                sm.checkPermission(new RuntimePermission("setContextClassLoader"));
            }
            this.acc = AccessController.getContext();
            this.ccl = Thread.currentThread().getContextClassLoader();
        }

        public Thread newThread(final Runnable r) {
            return super.newThread(new Runnable() {
                public void run() {
                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
                        public Void run() {
                            Thread.currentThread().setContextClassLoader(ccl);
                            r.run();
                            return null;
                        }
                    }, acc);
                }
            });
        }
    }

RejectedExecutionHandler

In the thread pool and use bounded queue time, if the queue is full, the task is added to the thread pool when there will be problems, you can specify processing strategy.

public interface RejectedExecutionHandler {
    void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

To solve these problems java thread pool provides the following strategies:

  • AbortPolicy

This policy is a default policy of the thread pool. Using this policy, if the thread pool queue is full RejectedExecutionException lose this task and throws an exception.

 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            //不做任何处理,直接抛出异常
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
  • DiscardPolicy

slient version of this strategy and AbortPolicy if the thread pool queue is full, it will directly lose this task and there will be no exceptions.

   public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        	//就是一个空的方法
        }
  • DiscardOldestPolicy

This strategy is also well understood literally, discard the oldest. This means that if the queue is full, the first task will be deleted to make room into the queue, and then try to join the queue.
Because the queue is the tail forward, the team head, so the head elements is the oldest, so every time before trying to remove the head element into the team.

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
            	//移除队头元素
                e.getQueue().poll();
                //再尝试入队
                e.execute(r);
            }
        }
  • CallerRunsPolicy

With this policy, if added to the thread pool fails, then the main thread to perform the task on their own , without waiting for thread pool thread to do it. Like a man of quick temper, I can not wait for someone else to do it will simply myself.

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                //直接执行run方法
                r.run();
            }
        }
  • customize

If these policies do not meet business scenario, you can define a deny policy, as long as the realization RejectedExecutionHandler interfaces , and methods to achieve rejectedExecution it. Specific logic method is defined in rejectedExecution go on OK.

Create a thread pool

newFixedThreadPool

Create reusable and fixed number of threads in the thread pool, if all the threads in the pool are active, then re-submit the job waits in the queue until a thread is available; if the thread pool is a thread due to an exception At the end, the thread pool will then complement a new thread .


//corePoolSize==maximumPoolSize
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(
    nThreads,
    nThreads,
    0L, 
    TimeUnit.MILLISECONDS,
    //使用一个基于FIFO排序的阻塞队列,在所有corePoolSize线程都忙时新任务将在队列中等待
     new LinkedBlockingQueue<Runnable>()
);
}


newSingleThreadExecutor

Creating a single-threaded Executor, if the thread is ended because of an exception to build a new thread to continue to execute subsequent tasks

//corePoolSize和maximumPoolSize都等于,表示固定线程池大小为1
public static ExecutorService newSingleThreadExecutor() {
   return new FinalizableDelegatedExecutorService
                     //corePoolSize和maximumPoolSize都等于,表示固定线程池大小为1
                        (new ThreadPoolExecutor(1, 
                                                1,
                                                0L, TimeUnit.MILLISECONDS,
                                                new LinkedBlockingQueue<Runnable>()));


newScheduledThreadPool

Creates a thread pool regularly perform or delay execution

    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }


    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }


newCachedThreadPool

Creating a cached thread pool, if the threads in the pool in 60 seconds is not in use will be removed , when performing a new task, when there are available threads in the thread pool to reuse previously created threads available, otherwise the new a thread



public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  //使用同步队列,将任务直接提交给线程
                                  new SynchronousQueue<Runnable>());
}

Extended ExecutorService

DelegatedExecutorService

The method proxy mode, other ExecutorService package, the package need only

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

FinalizableDelegatedExecutorService

DelegatedExecutorService subclass implement finalize method.

    static class FinalizableDelegatedExecutorService
        extends DelegatedExecutorService {
        FinalizableDelegatedExecutorService(ExecutorService executor) {
            super(executor);
        }
        protected void finalize() {
            super.shutdown();
        }
    }

DelegatedScheduledExecutorService

DelegatedExecutorService subclass method implemented schedule.

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

 

Guess you like

Origin blog.csdn.net/demon7552003/article/details/92071334