java中常用的五种线程池的实现

时间:2022-12-01 15:17:24

线程池介绍:

多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,
增加处理器单元的吞吐能力。 假设一个服务器完成一项任务所需时间为: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--------------"); } }