多线程学习笔记

1.ThreadPoolExecutor(线程池类)

new ThreadPoolExecutor(
		         int corePoolSize,//核心线程池大小
                              int maximumPoolSize,//最大线程池大小
                              long keepAliveTime,//线程池中超过corePoolSize数目的空闲线程最大存活时间;可以allowCoreThreadTimeOut(true)成为核心线程的有效时间
                              TimeUnit unit,//keepAliveTime的时间单位
                              BlockingQueue workQueue,//阻塞任务队列
                              ThreadFactory threadFactory,//线程工厂
                              RejectedExecutionHandler handler//当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理
)

2.自定义线程池

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 自定义线程池
* @ClassName:MyExecutor .java
* @Description:功能描述
* @author:  heweitao
* @date:    2018年9月5日
 */
public class MyExecutor extends ThreadPoolExecutor {

	private Logger log = LoggerFactory.getLogger(getClass());

	/**
	 * 缓存中任务超时时间,单位毫秒.超时的请求将会被直接删除.
	 */
	private long taskTimeoutMillis = 30 * 1000;

	/**
	 * 线程池核心线程数.
	 */
	private int corePoolSize = 1;
	
	/**
	 * 任务缓存,用于并发控制.
	 */
	private CopyOnWriteArrayList cacheTaskList = new CopyOnWriteArrayList();
	
	
	public MyExecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, new ThreadPoolExecutor.CallerRunsPolicy());
		this.corePoolSize = corePoolSize;
	}

	/**
	 * 
	 * @description:重写execute方法,加入线程队列时,cacheTaskList缓存任务
	 * @param command
	 * @return void(返回值说明)
	 * @exception/throws
	 * @author kason 2015年10月28日
	 */
	@Override
	public void execute(Runnable command) {
		cacheTaskList.add(command);
		super.execute(command);
	}
	
	@Override
	protected void afterExecute(Runnable r, Throwable t) {
		try {
			// 任务执行完成后,删除缓存中该任务
			cacheTaskList.remove(r);

	// 删除任务缓存中超时的请求,避免线程池满.
	if (cacheTaskList.size() >= corePoolSize) {
		deleteTimeoutTask();
	}
	} catch (Exception e) {
		log.error("线程池 afterExecute() Exception" + e.getMessage(), e);
	} finally {
		super.afterExecute(r, t);
	}
	}
	
	
	/**
	 * 查询线程池中任务数量.
	 * 
	 */
	public long getRunnableSize() {
		return cacheTaskList.size();
	}
	
	/**
	 * 删除任务缓存中超时的请求.
	 * 
	 */
	public void deleteTimeoutTask() {
		try {
			long currentTimes = System.currentTimeMillis();
			for (int i = 0; i < cacheTaskList.size(); i++) {
				SeaExamTaskThread t = (SeaExamTaskThread) cacheTaskList.get(i);
				long useTimes = currentTimes - t.getStartTimeMillis();
				if (useTimes > taskTimeoutMillis) {
					cacheTaskList.remove(t);
					log.warn("remove timeout task: " + t.getTaskId());
				}
			}
		} catch (Exception e) {
			log.error("deleteTimeoutTask 异常", e);
		}
	}
	
	/**
	 * 查询线程池中任务耗时统计信息.
	 * 
	 */
	public String getRunnableTuskTimes(String priorityKey) {
		String result = "";

	long less30m = 0;
	long between30to60 = 0;
	long between60to3600 = 0;
	long morethan3600 = 0;
	long others = 0;

	long currentTimes = System.currentTimeMillis();
	for (int i = 0; i < cacheTaskList.size(); i++) {
		long useTimes = currentTimes - ((SeaExamTaskThread) cacheTaskList.get(i)).getStartTimeMillis();
		useTimes = useTimes / 1000;
		if (useTimes < 30) {
			less30m += 1;
		} else if (useTimes >= 30 && useTimes < 60) {
			between30to60 += 1;
		} else if (useTimes >= 60 && useTimes < 3600) {
			between60to3600 += 1;
		} else if (useTimes > 3600) {
			morethan3600 += 1;
		} else {
			others += 0;
		}
	}

	result = priorityKey + "队列线程池缓存任务加入时间统计:\n";
	result += "启动<30秒: " + less30m + "\n";
	result += "启动[30-60)秒: " + between30to60 + "\n";
	result += "启动[60-3600)秒: " + between60to3600 + "\n";
	result += "启动3600秒及以上: " + morethan3600 + "\n";
	result += "others: " + others + "\n";

	return result;
	}
}

3.自定义线程类

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 线程任务
 * 
 * @ClassName:TaskThread .java
 * @Description:功能描述
 * @author: heweitao
 * @date: 2018年9月6日
 */
public class TaskThread implements Runnable {

        private Logger log = LoggerFactory.getLogger(getClass());

        /**
         * 线程生成时间,用于线程状态监控.
         */
        private long startTimeMillis = System.currentTimeMillis();


        public TaskThread() {
                
        }


        @Override
        public void run() {
                //这里编写需要执行的任务
        }

        /**
         * 获取线程生成时间.
         */
        public long getStartTimeMillis() {
                return startTimeMillis;
        }
        
        public Long getTaskId() {
                return seaQuestionDTO.getQuestionId();
        }
}

4.任务队列

import java.util.concurrent.ConcurrentLinkedQueue;

import net.shadowedu.hfls.core.base.dto.SeaExamCorrectDTO;
import net.shadowedu.hfls.core.base.dto.SeaQuestionDTO;

/**
 * 题库任务队列
* @ClassName:TaskQueue .java
* @Description:功能描述
* @author:  heweitao
* @date:    2018年9月6日
 */
public class TaskQueue {

        public static long MAX_CACHE_SIZE = 60;

        /**
         * 非阻塞队列.
         */
        private static ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

        /**
         * 
         * @description:把任务插入一个队列
         * @param task
         * @return void (返回值说明)
         */
        public static synchronized void pushTask(DTO task) {
                try {
                        queue.add(task);
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

        /**
         * 获取队列剩余请求数
         * 
         * @description:
         * @param taskKey
         * @return(设定参数) @return int(返回值说明)
         */
        public static synchronized long getTaskQueueLen() {
                return queue.size();
        }

        /**
         * 
         * @description:取出队列中的Task
         * @param taskKey
         * @return(设定参数) @return Task(返回值说明)
         */
        public static synchronized DTOpopTask() {
                DTOtask = null;
                try {
                        task = queue.poll();
                } catch (Exception e) {
                        e.printStackTrace();
                }
                return task;
        }
}

5.线程管理(启动)类

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class TaskManagerThread extends Thread {

        private Logger log = LoggerFactory.getLogger(getClass());
        // 调试标志
        private boolean isDebug = false;
        private long sleepTime = 100;
        private int corePoolSize = 40;
        private int maximumPoolSize = 60;
        private SeaQuestionPoolExecutor executor;
        public TaskManagerThread() {
                executor = new SeaQuestionPoolExecutor(corePoolSize, maximumPoolSize, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(20));
        }

        

        @Override
        public void run() {//循环执行,无间断的判断有无任务
                while (true) {
                        try {
                                addTaskThread();
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                }
        }
        
        private void addTaskThread() {
                try {
                        Long redisCachedTaskNum = TaskQueue.getTaskQueueLen();
                        if (redisCachedTaskNum <= 0) {
                                Thread.sleep(sleepTime);
                        }

        if (isDebug) { 
                long runTaskNum = executor.getRunnableSize();
                if (isDebug) {
                        log.info("题库线程池信息: {runables:" + runTaskNum + ", threadNum: " + maximumPoolSize + "}");
                        if (runTaskNum > 10) {
                                log.info(this.executor.getRunnableTuskTimes("TaskThread"));
                        }
                }
        }
        while (executor.getRunnableSize() < maximumPoolSize) {
                //这里添加需要运作的线程以及任务
                TaskThread thread = new Thread();
                executor.execute(thread);
        }

        } catch (Exception e) {
                log.error("线程池错误: ", e);
                e.printStackTrace();
        }
        }

        public void setSeaQuestionService(SeaQuestionService seaQuestionService) {
                this.seaQuestionService = seaQuestionService;
        }

        public void setSeaQuestionBankService(SeaQuestionBankService seaQuestionBankService) {
                this.seaQuestionBankService = seaQuestionBankService;
        }
        
        
}

 

你可能感兴趣的:(java)