封装线程池工具类

封装线程池工具类

最近发现当需要对某业务分拆多个模块同时执行,且不要求返回结果时,用到了线程池,可是线程池又没有地方关闭,消耗一定资源,因此封装一个线程池工具类,设定线程池大小,设定执行顺序,实例化一个对象,用该对象管理上述业务,用完即关闭。

代码如下:

package com.util.thread_tool;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSONObject;

/**
* Description: 多线程并行工具类
* @author: wyh 
* @date 2020年8月7日
 */
public class ThreadTool {
	/**
	 * 执行线程数
	 */
	private int size;
	
	/**
	 * 当前完成执行线程数
	 */
	private int currentFinishSizeRecord;
	
	/**
	 * 缓存线程池
	 */
	private ExecutorService pool = null;
	
	/**
	 * 执行顺序 - FIFO:先进先出,顺序执行
	 */
	public final static String ORDER_TYPE_FIFO = "FIFO";
	
	/**
	 * 执行顺序 - CACHE:缓存,有空闲则执行
	 */
	public final static String ORDER_TYPE_CACHE = "CACHE";
	
	/**
	 * 执行顺序 - FIXED:缓存,固定数执行
	 */
	public final static String ORDER_TYPE_FIXED = "FIXED";
	
	/**
	 * 构造器初始化["执行线程数","缓存线程池","当前完成执行线程数"]
	 * @param size
	 * @throws Exception 
	 */
	public ThreadTool(int size, String orderType, Integer fixedNum) throws NullPointerException {
		this.size = size;
		switch(orderType) {
			case ORDER_TYPE_FIFO : 
				this.pool = Executors.newSingleThreadExecutor();
				break;
			case ORDER_TYPE_CACHE : 
				this.pool = Executors.newCachedThreadPool();
				break;
			case ORDER_TYPE_FIXED : 
				if(fixedNum == null || fixedNum == 0) {
					throw new NullPointerException("fixedNum is null.");
				}else {
					this.pool = Executors.newFixedThreadPool(fixedNum);
					break;
				}
			default :
				break;
		}
		this.currentFinishSizeRecord = 0;
	}
	
	/**
	 * 同步请求更改size
	 * @return
	 */
	private synchronized boolean setCurrentSizeRecord() {
		if((this.currentFinishSizeRecord+1) <= this.size) {
			this.currentFinishSizeRecord += 1;
			return true;
		}else {
			if(!pool.isShutdown()) {
				this.pool.shutdown();
			}
			System.out.println("线程池已满");
			return false;
		}
	}
	
	/**
	 *  执行的对象方法
	 * @param obj - 执行的对象实例
	 * @param methodName - 执行的方法名
	 * @param objs - 参数组,方法的传参,必须为对象
	 * @return
	 */
	public synchronized boolean execute(Object obj, String methodName, Object... objs) {
		if(!setCurrentSizeRecord()) {
			return false;
		}
		Thread thread = new Thread(()->this.threadExecute(obj, methodName, objs));
		pool.submit(thread);
		return false;
	}
	
	/**
	 * 获取当前完成的线程数
	 * @return
	 */
	public int currFinishSize() {
		return this.currentFinishSizeRecord;
	}
	
	/**
	 * 中途关闭线程池,池内未加的线程将不增加,池内已有线程将继续执行到结束
	 */
	public void shutdown() {
		this.size = 0;
		if(!pool.isShutdown()) {
			this.pool.shutdown();
		}
	}
	
	/**
	 * 执行方法
	 * @param obj - 执行的对象实例
	 * @param methodName - 执行的方法
	 * @param objs - 参数组
	 * @return
	 */
	public boolean threadExecute(Object obj, String methodName, Object... objs) {
		Class[] clzzs = new Class[objs.length];
		for(int i = 0; i < objs.length; i++) {
			clzzs[i] = objs[i].getClass();
		}
		try {
			Method method = obj.getClass().getDeclaredMethod(methodName, clzzs);
			Object value = method.invoke(obj, objs);
			// 处理返回值
			System.out.println("处理返回值,返回值内容 : " + JSONObject.toJSONString(value));
			return true;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	
		return false;
	
	}
}

测试代码如下:

public class Test {
	public static void main(String[] args) throws Exception {
		ThreadTool threadTool = new ThreadTool(5, ThreadTool.ORDER_TYPE_CACHE, null);
		for(int i = 0; i < 5; i++) {
			final int n = i;
			threadTool.execute(new Inner(), "say", "线程操作", n);
		}
		for(int i = 0; i < 5; i++) {
			final int n = i;
			threadTool.execute(new Inner2(), "add", n);
		}
		TimeUnit.SECONDS.sleep(2);
		System.out.println("finishSize : " + threadTool.currFinishSize());
	}
}

辅助测试代码如下:
Inner

public class Inner {
	
	/**
	 * 描述内容
	 * @param content 内容
	 * @param count 第几个
	 * @return
	 */
	public boolean say(String content, Integer count) {
		System.out.println("content : " + content + " , count : " + count);
		return true;
	}
}

Inner2

public class Inner2 {
	private static int size;
	public int add(Integer count) {
		this.size += count;
		System.out.println("累积 : " + size);
		return size;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Retank

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值