Java 多线程规范(2)线程池详解

来源:互联网 发布:android照相机源码 编辑:程序博客网 时间:2024/06/16 11:51

十四,线程池详解

之前我们已经了解ExecutorService接口声明的方法:
public abstract <T> T invokeAny(Collection<? extends Callable<T>>) throws InterruptedException,ExecutionExceptionpublic abstract <T> T invokeAny(Collection<? extends Callable<T>>,long,TimeUnit) throws InterruptedException,ExecutionException,TimeoutExceptionpublic abstract <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>>) throws InterruptedExceptionpublic abstract <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>>,long,TimeUnit) throws InterruptedExceptionpublic abstract <T> Future<T> submit(Runnable,T)public abstract <T> Future<T> submit(Callable<T>)public abstract boolean awaitTermination(long,TimeUnit) throws InterruptedExceptionpublic abstract boolean isShutdown()public abstract boolean isTerminated()public abstract List<Runnable> shutdownNow()public abstract Future<?> submit(Runnable)public abstract void execute(Runnable)  继承自Executor这个顶级接口public abstract void shutdown()

API线程池使用示例

使用线程池要自己设置参数,做到每个参数心中有数。
下面具体举个线程池的例子,这也是API中Executors.newCachedThreadPool();的实现

public class ThreadPoolTool {    public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(            0,             Integer.MAX_VALUE,            60L,             TimeUnit.SECONDS,            new SynchronousQueue<Runnable>());    public static void execute(Runnable command){        THREAD_POOL_EXECUTOR.execute(command);    }}

线程池几个参数的说明

参数名 说明 corePoolSize 核心线程数,一直存活,当小于核心线程数的时候优先创建(只有在工作队列满的情况下才会创建超出这个数量的线程) maximumPoolSize 线程池允许的最大线程数,当大于核心线程数且队列满,创建直到这个数 keepAliveTime 空闲线程超时间,当线程数多于核心线程数时,空闲的线程会在这个时间退出,直到线程数等于核心线程数 BlockingQueue<Runnable> workQueue 阻塞队列,如果是ArrayBlockingQueue可以限制队列大小

BlockingQueue是个接口,有几个很重要的子类

下面的表格要熟
Summary of BlockingQueue methods

Throws exception Special value Blocks Times out Insert add(e) offer(e) put(e) Remove remove() poll() take() Examine element() peek() not applicable

它有这么几个常用和不常用子类

子类名 说明 LinkedBlockingQueue 双向队列(双向链表实现,jedisPool用的正是这个) LinkedBlockingQueue 队列(单链表) 使用频率高 ArrayBlockingQueue 限制大小的队列 SynchronousQueue 空集合,put必须等待一个take,Executors.newCachedThreadPool();用的正是这个 ScheduledThreadPoolExecutor.DelayedWorkQueue 内部类不常用

线程池的几个例子

API 返回类型 说明 Executors.newFixedThreadPool(nThreads); ExecutorService 固定线程数的线程池,不可伸缩 Executors.newSingleThreadExecutor ExecutorService 单线程,等同于newFixedThreadPool(1) Executors.newCachedThreadPool() ExecutorService 相当于无限线程,空闲线程默认60秒超时销毁,适合于短任务 Executors.newScheduledThreadPool(corePoolSize); ScheduledExecutorService 支持定时周期执行任务

上面已经给出了Executors.newCacheThreadExector的例子
下面给是其他几个API的
串行Executors.newSingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {        return new FinalizableDelegatedExecutorService            (new ThreadPoolExecutor(1, 1,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue<Runnable>()));    }

固定大小Executors.newFixedThreadPool(int nThreads)

public static ExecutorService newFixedThreadPool(int nThreads) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>());    }

我们怎么优雅的使用线程池和他的接口?

public interface ThreadPool {    Executor getExecutor();}
public class FixedThreadPool implements ThreadPool {    public Executor getExecutor() {        String name = ThreadPoolConstants.DEFAULT_THREAD_NAME;        int threads = ThreadPoolConstants.DEFAULT_THREADS;        int queues = ThreadPoolConstants.DEFAULT_QUEUES;        return new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS,                 queues == 0 ? new SynchronousQueue<Runnable>() :                     (queues < 0 ? new LinkedBlockingQueue<Runnable>()                             : new LinkedBlockingQueue<Runnable>(queues)),                new NamedThreadFactory(name, true), new AbortPolicyWithReport(name));    }}

体会下

原创粉丝点击