线程池介绍:
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,
增加处理器单元的吞吐能力。 假设一个服务器完成一项任务所需时间为:T1 创建线程时间,
T2 在
线程中执行任务的时间,T3 销毁线程时间。
涉及的接口与类:
一.Java中的ThreadPoolExecutor类(该类有四种构造方法)
public
ThreadPoolExecutor(
int
corePoolSize,
int
maximumPoolSize,
long
keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue);
public
ThreadPoolExecutor(
int
corePoolSize,
int
maximumPoolSize,
long
keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
public
ThreadPoolExecutor(
int
corePoolSize,
int
maximumPoolSize,
long
keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
public
ThreadPoolExecutor(
int
corePoolSize,
int
maximumPoolSize,
long
keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
二.Java中的ExecutorService接口
可缓存线程池
Executors.newCachedThreadPool();
定长线程池
Executors.newFixedThreadPool(3);
定长线程池,定时器
Executors.newScheduledThreadPool(3);
单线程化的线程池
Executors.newSingleThreadExecutor();
三.Java中的ScheduledExecutorService接口
代码实现:代码中已经对各个方法有详细的注释,请仔细阅读注释;
package com.superb.juint_thread; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 该类中有五种实现线程池的方法,其中有三种通过ExecutorServic接口实现,一种 * 通过ScheduledExecutorService接口实现,另一种通过ThreadPoolExecutor类实现 * * 这里面将五种线程池用单例模式实现,当然也没必要用单例模式实现,这个完全根据项目的业务需要来定 * * @author superb * */ public class ThreadPoolUtil { private static ThreadPoolExecutor pool = null; /** 可缓存线程池 */ private static ExecutorService cachedPool = null; /** 定长线程池 */ private static ExecutorService fixedPool = null; /** 定长线程池,支持定时及周期性 */ private static ScheduledExecutorService schedulPool = null; /** 单例线程池 */ private static ExecutorService singlePool = null; private ThreadPoolUtil() { } /** * 得到一个ThreadPoolExecutor线程池 * new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, * long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, * RejectedExecutionHandler handler) * * @corePoolSize 线程池大小 * @maximumPoolSize 线程池最大值 * @keepAliveTime 线程保存的存活时间 * @workQueue 线程数超过线程大小时,任务存在这个队列中 * @handler 线程超过队列时,处理办法 * @return */ public static ThreadPoolExecutor newInstance(){ if(pool==null){ synchronized(ThreadPoolUtil.class){ if(pool==null){ pool = new ThreadPoolExecutor(3, 5, 10, TimeUnit.SECONDS, new ArrayBlockingQueue(10), new ThreadPoolExecutor.DiscardOldestPolicy()); } } } return pool; } /** * 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 * * 线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。 * @return CachedThreadPool */ public static ExecutorService cachedInstance(){ if(cachedPool == null){ synchronized (ThreadPoolUtil.class) { if(cachedPool==null){ cachedPool = Executors.newCachedThreadPool(); } } } return cachedPool; } /** * 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。(这里线程池大小为3) * * 定长线程池的大小最好根据系统资源进行设置 * * @return CachedThreadPool */ public static ExecutorService fixedInstance(){ if(fixedPool == null){ synchronized (ThreadPoolUtil.class) { if(fixedPool==null){ fixedPool = Executors.newFixedThreadPool(3); } } } return fixedPool; } /** * 创建一个定长线程池,支持定时及周期性任务执行,(定时任务) * * @return CachedThreadPool */ public static ScheduledExecutorService schedulInstance(){ if(schedulPool == null){ synchronized (ThreadPoolUtil.class) { if(schedulPool==null){ schedulPool = Executors.newScheduledThreadPool(3); } } } return schedulPool; } /** * 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行 * * 顺序执行各个任务。 * @return CachedThreadPool */ public static ExecutorService singleInstance(){ if(singlePool == null){ synchronized (ThreadPoolUtil.class) { if(singlePool==null){ singlePool = Executors.newScheduledThreadPool(10); } } } return singlePool; } } package com.superb.juint_thread; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 测试线程池的实现main类 * */ public class ThreadMain { public static void main( String[] args ){ //singleMethod(); //cachedMethod(); //schedulMethod(); //fixedMethod(); threadPoolMethod(); } /** * 描述: * 得到一个ThreadPoolExecutor线程池, * 通过new ThreadPoolExecutor()对象类来实现。 * 该方法new一个 (@corePoolSize) 线程池大小为 3 的线程池。 * 模拟任务有10个,每次执行三个,剩余的放在队列中等待执行 * * result: * ---------------BEGIN-------------- * ---------------END-------------- * -----------pool-1-thread-1---2016-08-12 05:47:13 * -----------pool-1-thread-2---2016-08-12 05:47:13 * -----------pool-1-thread-3---2016-08-12 05:47:13 * * -----------pool-1-thread-1---2016-08-12 05:47:15 * -----------pool-1-thread-3---2016-08-12 05:47:15 * -----------pool-1-thread-2---2016-08-12 05:47:15 * * -----------pool-1-thread-1---2016-08-12 05:47:17 * -----------pool-1-thread-3---2016-08-12 05:47:17 * -----------pool-1-thread-2---2016-08-12 05:47:17 * * -----------pool-1-thread-3---2016-08-12 05:47:19 */ public static void threadPoolMethod(){ ThreadPoolExecutor pool = ThreadPoolUtil.newInstance(); System.out.println("---------------BEGIN--------------"); for(int i = 0; i < 10; i++){ pool.execute(new Runnable() { public void run() { System.out.println("-----------"+Thread.currentThread().getName()+ "---"+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } System.out.println("---------------END--------------"); } /** * 描述: * 定时器,可以指定业务每隔指定时间执行一次,该方法中每隔 3 秒模拟一次业务处理 * result: * * 模拟业务处理=====2016-08-12 04:30:37 * 模拟业务处理=====2016-08-12 04:30:40 * 模拟业务处理=====2016-08-12 04:30:43 * 模拟业务处理=====2016-08-12 04:30:46 * 模拟业务处理=====2016-08-12 04:30:49 */ public static void schedulMethod(){ ScheduledExecutorService pool = ThreadPoolUtil.schedulInstance(); pool.scheduleAtFixedRate(new Runnable() { public void run() { System.out.println("模拟业务处理====="+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") .format(new Date())); } }, 0, 3, TimeUnit.SECONDS); } /** * 描述: * 线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。 * 结论: * 当每个任务执行5s时,任务间隔为2s时,上一个任务未执行完时,下一个任务已经开始,此时不会复用上一个线程。 * 当任务执行为2s,任务间隔为5s时,下一个任务开始时,上一个任务已完成,此时会复用上一个线程 * result 1: *
----------->BEGIN<-------*
------>pool-1-thread-1<------*
------>pool-1-thread-2<------*
------>pool-1-thread-3<------*
------>pool-1-thread-1<------*
------>pool-1-thread-2<------*
------>pool-1-thread-3<------*
----------->SUCCESS<------* * result 2: *
----------->BEGIN<-------*
------>pool-1-thread-1<------*
------>pool-1-thread-1<------*
------>pool-1-thread-1<------*
------>pool-1-thread-1<------*
----------->SUCCESS<------*/ public static void cachedMethod() { ExecutorService pool = ThreadPoolUtil.cachedInstance(); System.out.println("
----------->BEGIN<-------"); for (int i = 0; i < 10; i++) { pool.execute(new Runnable() { public void run() { System.out.println("
------>" + Thread.currentThread().getName() + "<------"); try { Thread.sleep(5000);// 每个任务执行5s, } catch (InterruptedException e) { e.printStackTrace(); } } }); try { Thread.sleep(2000);// 每个任务间隔2s } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("
----------->SUCCESS<------"); } /** * 描述: * 定长线程池,可控制线程最大并发数,超出的线程会在队列中等待, * 该方法中我们实行了一个长度为3的线程池,其中开启10个任务,每次只执行3个任务, * 剩余任务会在队列中等待,直到有线程空闲执行下一个任务 * result: * ---------------BEGIN-------------- * ---------------END-------------- * ----模拟任务----pool-1-thread-2----2016-08-12 05:09:02 * ----模拟任务----pool-1-thread-1----2016-08-12 05:09:02 * ----模拟任务----pool-1-thread-3----2016-08-12 05:09:02 * * ----模拟任务----pool-1-thread-3----2016-08-12 05:09:07 * ----模拟任务----pool-1-thread-2----2016-08-12 05:09:07 * ----模拟任务----pool-1-thread-1----2016-08-12 05:09:07 * * ----模拟任务----pool-1-thread-3----2016-08-12 05:09:12 * ----模拟任务----pool-1-thread-2----2016-08-12 05:09:12 * ----模拟任务----pool-1-thread-1----2016-08-12 05:09:12 * * ----模拟任务----pool-1-thread-3----2016-08-12 05:09:17 * */ public static void fixedMethod() { ExecutorService pool = ThreadPoolUtil.fixedInstance(); System.out.println("---------------BEGIN--------------"); for (int i = 0; i < 10; i++) { pool.execute(new Runnable() { public void run() { System.out.println("----模拟任务----"+Thread.currentThread().getName() + "----"+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())); try { Thread.sleep(5000);//模拟每隔线程执行5s } catch (InterruptedException e) { e.printStackTrace(); } } }); } System.out.println("---------------END--------------"); } /** * 描述: * 结果依次输出,相当于顺序执行各个任务 * result: * ---------------BEGIN-------------- * 当前执行任务index值为:1 * 当前执行任务index值为:2 * 当前执行任务index值为:3 * 当前执行任务index值为:4 * 当前执行任务index值为:5 * 当前执行任务index值为:6 * 当前执行任务index值为:7 * 当前执行任务index值为:8 * 当前执行任务index值为:9 * ---------------END-------------- */ public static void singleMethod() { ExecutorService pool = ThreadPoolUtil.singleInstance(); System.out.println("---------------BEGIN--------------"); for (int i = 1; i < 10; i++) { final int index = i; pool.execute(new Runnable() { public void run() { System.out.println("当前执行任务index值为:"+index); } }); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("---------------END--------------"); } }