一个简单线程的创建和销毁如下代码,与进程进程相比,线程是一种轻量级的工具,但是轻量并不代表没有,它的创建和关闭依然需要花费时间,如果创建和销毁的时间还大于线程本身完成的工作,那就会得不偿失,甚至会造成Out of Memory。即使没有,大量的线程回收也会给GC带来巨大的压力。为了解决这样的问题,那么线程池应运而生。
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}).start();
线程池和数据库连接池是类似的概念,在池中总有那么几个活跃的线程,当程序中线程时,从池中取出一个,用完后不直接关闭,而是放回池中。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
/**
*
* @param corePoolSize 线程池中线程的数量
* @param maximumPoolSize 最大线程数量
* @param keepAliveTime 线程数超过指定的数量,多于线程的最大存活时间
* @param unit 存活时间的单位
* @param workQueue 任务队列,提交,但是还没有执行的任务
* @param threadFactory 创建线程的工厂
* @param handler 任务太多时,拒绝任务的策略
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
//... 核心实现
}
ThreadPoolExecutor 的构造函数参数中,其他的都比较简单,详细看一下 workQueue (任务队列)和 handler ( 拒绝策略)
workQueue :BlockingQueue
handler 拒绝策略 :JDK内置了四种拒绝策略如下:
下面是一个例子:
public class ExtThreadPool {
public static void main(String[] args) throws InterruptedException {
ExecutorService es = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(), new ThreadFactory() {
// 自定义线程创建的方法,可设置线程的相关属性
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
System.out.println("创建线程" + t);
return t;
}
}) {
// 扩展线程池,增强线程执行之前 之后,以及结束的相关操作
@Override
protected void beforeExecute(Thread t, Runnable r) {
System.out.println(((MyTask) r).name + "执行之前");
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
System.out.println(((MyTask) r).name + "执行完毕");
}
@Override
protected void terminated() {
System.out.println("线程退出!!!");
}
};
for (int i = 0; i < 5; i++) {
MyTask task = new MyTask("Task" + i);
es.execute(task); // 特别注意,在线程池中尽量使用execute()方法提交任务,否则程序出错信息看不到、很痛苦
Thread.sleep(1000);
}
es.shutdown();
}
// 静态内部类
public static class MyTask implements Runnable {
public String name;
public MyTask(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("正在执行的线程" + Thread.currentThread().getId() + " " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}