线程池一
线程池
要使用多线程的时候,直接new Thread(new Runable(){XXXX}).start(),这样创建一个线程很简单,很快。
但是假如需要创建大量的线程的时候,这样频繁的创建,销毁线程会大大的降低系统效率,那我们能不能重用线程的?
在JAVA中我们可以通过线程池来达到此目的,来看看这个ThreadPoolExecutor 类
ThreadPoolExecutor
ThreadPoolExecutor 是java 1.5 的 java.util.concurrent 包的 一个类,也是java 线程池里面最重要的一个类,来看看它
public class ThreadPoolExecutor extends AbstractExecutorService {
。。。。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
}
从其给出的构造函数,里面的参数
int corePoolSize 核心线程数,当线程池创建后,默认情况线程池里面只有0个线程,当任务来了则创建线程执行任务,当线程池线程数目达到 corePoolSize 时则将任务加入到缓存队列
int maximumPoolSize 最大线程数,当前线程池允许创建的最大线程数目
long keepAliveTime 此只当当前线程数目大于corePoolSize的时候,才会生效,是指线程在没有任务的时候,会存活多久。
TimeUnit unit 枚举类型,为keepAliveTime的单位
BlockingQueue
LinkedBlockingQueue
SynchronousQueue
ThreadFactory threadFactory 创建Thread的工厂类
RejectedExecutionHandler handler 当拒绝处理任务时的策略。
ThreadPoolExecutor.AbortPolicy 丢弃任务并抛出RejectedExecutionException异常。默认的
ThreadPoolExecutor.DiscardPolicy 也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy 由调用线程处理该任务
来看看AbstractExecutorService 这个抽象类
public abstract class AbstractExecutorService implements ExecutorService {
。。。。
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
。。。。
}
可以看出其实现了ExecutorService 接口,并将一些方法实现了,看看ExecutorService接口,已经其几个比较重要的方法
public interface ExecutorService extends Executor {
void shutdown(); //此方法会将则线程池关闭,不再接受任务,当时会将之前的任务执行完毕,当线程池处于关闭状态时,调用不会副作用
List<Runnable> shutdownNow(); //尝试停止所有正在执行的任务,返回在等待队列里面的任务。
boolean isShutdown(); //判断是否关闭
<T> Future<T> submit(Callable<T> task); // 执行该方法并返回一个可以获取执行结果的类 Future,其最后也是调用execute(Runnable command) 方法
Future<?> submit(Runnable task);
。。。。
}
来看一下 Executor这个顶级接口,
public interface Executor {
void execute(Runnable command);
}
从这整个体系来看,Executor是顶级接口,其就定义了一个方法 execute() 。执行Runnable ,其可能是用一个新的Thread执行,也可能是在线程池里面的Thread执行。