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

43 篇文章 0 订阅
16 篇文章 2 订阅
十四,线程池详解
之前我们已经了解ExecutorService接口声明的方法:
public abstract <T> T invokeAny(Collection<? extends Callable<T>>) throws InterruptedException,ExecutionException
public abstract <T> T invokeAny(Collection<? extends Callable<T>>,long,TimeUnit) throws InterruptedException,ExecutionException,TimeoutException
public abstract <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>>) throws InterruptedException
public abstract <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>>,long,TimeUnit) throws InterruptedException
public abstract <T> Future<T> submit(Runnable,T)
public abstract <T> Future<T> submit(Callable<T>)
public abstract boolean awaitTermination(long,TimeUnit) throws InterruptedException
public 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 exceptionSpecial valueBlocksTimes out
Insertadd(e)offer(e)put(e)
Removeremove()poll()take()
Examineelement()peek()not applicable

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

子类名说明
LinkedBlockingDeque双向队列(双向链表实现,jedisPool用的正是这个)
LinkedBlockingQueue队列(单链表) 使用频率高
ArrayBlockingQueue限制大小的队列
SynchronousQueue空集合,put必须等待一个take,Executors.newCachedThreadPool();用的正是这个
ScheduledThreadPoolExecutor.DelayedWorkQueue内部类不常用
线程池的几个例子
API返回类型说明
Executors.newFixedThreadPool(nThreads);ExecutorService固定线程数的线程池,不可伸缩
Executors.newSingleThreadExecutorExecutorService单线程,等同于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));
    }

}

体会下

对于线程池的线程数大小,举个例子,假设corePoolSize是5,maxPoolSize大小是10,阻塞队列大小是4。
当有任务进来的时候,线程池从0开辟新的线程达到1。不管这个线程有没有结束新的任务来了会在开辟新的线程而不是复用第一个,直到达到核心线程数5。如果此时有更多的并发任务上来,则放大任务队列里,如果任务队列满了,则开辟新线程直到最大线程数,如果最大线程数也满了则执行拒绝策略

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值