Java自制线程池


1.简介

1.1.线程池

1.2.线程池作用

1.3.线程池优点

1.4.JDK自带线程池

1.4.1.ThreadPoolExecutor

2.自制线程池

2.1.线程池主体类

2.2.任务类

2.3.测试类

简介

线程池

线程池的基本思想是一种对象池的思想,先开辟一块内存空间,开许多等待任务的线程,一旦有任务出现就直接使用线程池中的线程来进行任务,等到任务结束后再将这个线程放入线程池中,池中的执行调度由线程池管理器来管理。

线程池作用

线程池的作用就是更好的对系统中的线程进行管理,根据系统的环境清空,可以自动或者手动的设置线程数量,达到运行的最佳效果。

线程池优点

相对于不使用线程池来说,使用线程池有什么优点呢?

减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,用完以后可以再用。

可以根据系统的能力,自由的控制线程池的大小,防止在没有使用线程池的且对线程没有进行很好的管理的条件下服务器消耗过多的内存而宕机

JDK自带线程池

自从JDK1.5之后加入java.util.concurrent包后,线程池得到了极大的优化,现在只要按照提供的API来使用,我们就可以非常容易的使用JDK自带的线程池,为我们在写自己的程序时提供了极大的方便。

ThreadPoolExecutor

先来看看ThreadPoolExecutor的完整构造方法

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

对于里面的参数含义如下:

corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize - 池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
threadFactory - 执行程序创建新线程时使用的工厂。
handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
下面介绍一些常用的线程池:

newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

对应的构造方法

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

使用方法示例

//创建一个单线程的线程池
ExecutorService pool = Executors.newSingleThreadExecutor();
//创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
Thread t1 = new MyThread();
//将线程放入池中进行执行
pool.execute(t1);
//关闭线程池
pool.shutdown();

newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

对应的构造方法

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

使用方法示例

//创建一个可重用固定线程数的线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
//创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
Thread t1 = new MyThread();
//将线程放入池中进行执行
pool.execute(t1);
//关闭线程池
pool.shutdown();

newCachedThreadPool:创建一个可缓存的无界线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

对应的构造方法

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

使用方法示例

//创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们
ExecutorService pool = Executors.newCachedThreadPool();
//创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
Thread t1 = new MyThread();
//将线程放入池中进行执行
pool.execute(t1);
//关闭线程池
pool.shutdown();

newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

使用方法示例

////创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
ExecutorService pool = Executors.newScheduledThreadPool(2);
//创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
Thread t1 = new MyThread();
Thread t2 = new MyThread();
//将线程放入池中进行执行
pool.execute(t1);
//使用延迟执行风格的方法
pool.schedule(t2, 10, TimeUnit.MILLISECONDS);
//关闭线程池
pool.shutdown();

更多详情见请继续阅读下一页的精彩内容:

  • 1
  • 2
  • 下一页

相关内容