再后来有机会了解了Nginx 其中Nginx配置重复提交现象 我从前台提交一个get请求。后台处理了两次!顿时引起了我的注意。再继续了解到F5也有tiemout属性配置,然后再通过后台数据重复提交的间隔大概都是5分钟,联想到timeout属性配置是300秒才意识到是执行的业务方法时间过长,浏览器得不到响应F5自动触发了二次请求。
package net.uni.ap.thread;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 处理内容:线程池工厂类
*/
public class ThreadPoolExecutorFactory {
/**
* corePoolSize 池中所保存的线程数,包括空闲线程。
*/
private static final int corePoolSize = 40;
/**
* maximumPoolSize - 池中允许的最大线程数(采用LinkedBlockingQueue时没有作用)。
*/
private static final int maximumPoolSize = 40;
/**
* keepAliveTime -当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间,线程池维护线程所允许的空闲时间
*/
private static final int keepAliveTime = 60;
/**
* 执行前用于保持任务的队列(缓冲队列)
*/
private static final int capacity = 300;
/**
* 线程池对象
*/
private static ThreadPoolExecutor threadPoolExecutor = null;
//构造方法私有化
private ThreadPoolExecutorFactory(){}
public static ThreadPoolExecutor getThreadPoolExecutor(){
if(null == threadPoolExecutor){
ThreadPoolExecutor t;
synchronized (ThreadPoolExecutor.class) {
t = threadPoolExecutor;
if(null == t){
synchronized (ThreadPoolExecutor.class) {
t = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS,new LinkedBlockingQueue(),new ThreadPoolExecutor.DiscardOldestPolicy());
}
threadPoolExecutor = t;
}
}
}
return threadPoolExecutor;
}
}
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
其实你可以自己new一个ThreadPoolExecutor,来达到自己的参数可控的程度,例如,可以将LinkedBlockingQueue换成其它的(如:SynchronousQueue),只是可读性会降低,这里只是使用了一种设计模式。我们现在来看看ThreadPoolExecutor的源码是怎么样的。这里来看下构造方法中对那些属性做了赋值
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
这里你可以看到最终赋值的过程,可以先大概知道下参数的意思:
//corePoolSize 核心线程池数量(在线程数量小于corePoolSize时,新增加执行任务时会优先
//创建新的线程执行该任务,在=核心线程池数量时,会将任务加入BlockingQueue阻塞队列,当队
//列满时会又创建新的线程执行该任务,直到等于maximumPoolSize,当更进一步的时候将会执
//行reject(command))
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
if (runState == RUNNING && workQueue.offer(command)) {
if (runState != RUNNING || poolSize == 0)
//队列满且线程池调用了shutdown后,还在调用execute方法
ensureQueuedTaskHandled(command);
}
else if (!addIfUnderMaximumPoolSize(command))
reject(command); // is shutdown or saturated
}
}
package net.uni.ap.thread;
/**
*
* 处理内容:线程处理类
* @version: 1.0
* @see:net.uni.ap.thread.IThreadPoolExecutorHandler.java
* @date:2015-5-13
* @author:梅海波
*/
public interface IThreadPoolExecutorHandler extends Runnable{
}
package net.uni.ap.thread;
import java.lang.reflect.Method;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ThreadHandler extends ThreadHandlerAbstract{
private static final Logger logger = LoggerFactory.getLogger(ThreadHandler.class);
protected T t;
protected Class modelClass;
protected String method = "";
@SuppressWarnings("unchecked")
public ThreadHandler(Integer threadCount,T t){
this.t = t;
modelClass = (Class) t.getClass();
if(null != threadCount){
super.countDownLatch = new CountDownLatch(threadCount);
}
}
@Override
public void run() {
try{
Method[] methods = this.modelClass.getMethods();
for (Method method : methods) {
if(method.getName().equals(this.method)){
method.invoke(t);
}
}
if(null != super.countDownLatch){
super.countDownLatch.countDown();
}
if(null != ThreadPoolExecutorFactory.getThreadPoolExecutor().getQueue() && (ThreadPoolExecutorFactory.getThreadPoolExecutor().getQueue().size() < 20
|| ThreadPoolExecutorFactory.getThreadPoolExecutor().getQueue().size() == 0 )){
ThreadPoolExecutorFactory.getThreadPoolExecutor().setCorePoolSize(20);
}else{
ThreadPoolExecutorFactory.getThreadPoolExecutor().setCorePoolSize(40);
}
}catch (Exception e) {
e.printStackTrace();
logger.error("线程池处理异常 方法:" + this.method,e);
}
}
@Override
public void execute(IThreadPoolExecutorHandler threadPoolExecutorHandler,String method)throws Exception{
this.method = method;
try {
ThreadPoolExecutor threadPoolExecutor = ThreadPoolExecutorFactory.getThreadPoolExecutor();
threadPoolExecutor.execute(threadPoolExecutorHandler);
} catch (Exception e) {
e.printStackTrace();
logger.error("线程池处理异常 execute 方法:" + this.method,e);
throw new Exception(e.getMessage(),e);
}
}
@Override
public void await() throws Exception {
try {
if(super.countDownLatch != null){
countDownLatch.await();
}
} catch (Exception e) {
e.printStackTrace();
logger.error("线程池处理异常 await 方法:" + this.method,e);
throw new Exception(e.getMessage(),e);
}
}
@Override
public void shutdown() throws Exception {
try {
ThreadPoolExecutor threadPoolExecutor = ThreadPoolExecutorFactory.getThreadPoolExecutor();
threadPoolExecutor.shutdown();
} catch (Exception e) {
e.printStackTrace();
logger.error("线程池处理异常 shutdown 方法:" + this.method,e);
throw new Exception(e.getMessage(),e);
}
}
public int getPoolSize(){
ThreadPoolExecutor threadPoolExecutor = ThreadPoolExecutorFactory.getThreadPoolExecutor();
return threadPoolExecutor.getPoolSize();
}
/**
* 获取线程池队列状态数量
* @return
* @方法说明
* @date 2015-8-26
* @author 梅海波
*/
public int getQueueSize(){
ThreadPoolExecutor threadPoolExecutor = ThreadPoolExecutorFactory.getThreadPoolExecutor();
return threadPoolExecutor.getQueue().size();
}
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = ThreadPoolExecutorFactory.getThreadPoolExecutor();
for (int i = 0; i < 10000; i++) {
final int index = i;
threadPoolExecutor.execute(
new Runnable() {
@Override
public void run() {
try {
System.out.println(index + "队列数:" + ThreadPoolExecutorFactory.getThreadPoolExecutor().getQueue().size());
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
package net.uni.ap.thread;
import java.util.concurrent.CountDownLatch;
public abstract class ThreadHandlerAbstract implements IThreadPoolExecutorHandler {
/**
* 一个任务分多个线程处理时使用
*/
protected CountDownLatch countDownLatch = null;
public ThreadHandlerAbstract(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
public ThreadHandlerAbstract(){}
public abstract void execute(IThreadPoolExecutorHandler threadPoolExecutorHandler,String method)throws Exception;
public abstract void await()throws Exception;
public abstract void shutdown()throws Exception;
}