线程池创建线程异步获取Future超时

ExecutorService executorServer = xxxxxx.getThreadPool();

Future future = executorServer.submit(new xxxxxxx(Param, funcId));


 Object obj = future.get(100, TimeUnit.MILLISECONDS); //总超时时间设置

其中,future.get是从开始进行get方法时进行计算的时间,非future生成开始计算的,即什么时候get什么时候开始计时。

线程池从生成线程,如果核心线程不为0,则有任务时一直生成核心线程,直至到核心线程,之后开始方队列中,最后任务多就开始开辟新线程到最大线程数。

执行任务时,首先线程池开辟线程,之后 线程start( execute方法->addWorker-->t.start())后开始执行call方法。但从.start 到 执行call方法,需要CPU进行线程的上下文切换。 可以根据重写的

ThreadPoolExecutor方法来跟踪。

在高并发下,如果线程池不加 executorServer.prestartAllCoreThreads();

则在线程为1500的并发下,即新创建线程start状态为NEW,真正运行时为RUNNABLE(start后),到call真正的调用会耗时,因CPU切换。

如不加,则会有12-160多ms的消耗,

如果加上prestartAllCoreThreads()则性能会好很多,最大从start到call才3ms.

同时,如使用hutool-all-5.3.8.jar的ThreadUtil.execAsyn方法效果也比较好,但没有restartAllCoreThreads()这个好,测试效果有9-14ms的消耗。

public static ThreadPoolExecutor getThreadPool() {
if (executorServer == null || executorServer.isShutdown() || executorServer.isTerminated()) {
			synchronized (JzPreCheckUtil.class) {
				if (executorServer == null || executorServer.isShutdown() || executorServer.isTerminated()) {
					XxxConfig.isJzPrecheckEnabled(); //加载相关配置
					log.info("corePoolSize="+XxxConfig.corePoolSize+"  maximumPoolSize="+XxxConfig.maximumPoolSize+" keepAliveTime="+XxxConfig.keepAliveTime);
					ThreadFactory threadFactory = new ThreadFactory() {
						@Override
						public Thread newThread(Runnable r) {
							long t1=System.currentTimeMillis();
							String threadName="jzThreadPool" + r.hashCode();
							Thread newThread=new Thread(r, threadName);
							long t2=System.currentTimeMillis();
							log.info("创建线程="+threadName+" t1="+t1+"  t2="+t2+"  时间差="+(t2-t1));
							return newThread;
						}
					};

				
					executorServer = new ThreadPoolExecutor(XxxConfig.corePoolSize, XxxConfig.maximumPoolSize, XxxConfig.keepAliveTime, TimeUnit.SECONDS, new SynchronousQueue(),threadFactory);
					executorServer.prestartAllCoreThreads();

					log.info("prestartAllCoreThreads 之后="+executorServer.getQueue().size()+"  线程活着的数量="+executorServer.getActiveCount()+
							"  核心线程="+executorServer.getCorePoolSize()+"  最大线程="+executorServer.getMaximumPoolSize()+
							"  线程数="+executorServer.getPoolSize());
					
				}
			}
		}	
		log.info("queue 长度  后="+executorServer.getQueue().size()+"  线程活着的数量="+executorServer.getActiveCount()+
				"  核心线程="+executorServer.getCorePoolSize()+"  最大线程="+executorServer.getMaximumPoolSize()+
				"  线程数="+executorServer.getPoolSize());

		return executorServer;
	}
   @Override
    public Object call() throws Exception {
      
        xxx
        return out;
      
    }

重写

ThreadPoolExecutor参考:
package com.stock.framework.precheck.test2;

import com.stock.framework.jzprecheck.JzConfig;
import org.slf4j.Logger;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

public class MyThreadPool2 extends ThreadPoolExecutor {

    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

    public static Logger log = XXConfig.log;

    public MyThreadPool2(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    public MyThreadPool2(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public MyThreadPool2(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public MyThreadPool2(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    public MyThreadPool2 getThreadPool(){

      //  return XXXXUtil.getMyThreadPool();

        return null;
    }

    @Override
    public void execute(Runnable command) {

        log.info("execute-11="+System.currentTimeMillis());
        if (command == null){
            throw new NullPointerException();
        }


        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        AtomicInteger ctl=getCtl();
        int c = ctl.get();
        if (workerCountOf(c) < getCorePoolSize()) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        log.info("execute-22="+System.currentTimeMillis());
        BlockingQueue workQueue= (BlockingQueue) getPrivateValue(null,"workQueue");

        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

    public void reject(Runnable command) {
        RejectedExecutionHandler handler= (RejectedExecutionHandler) getPrivateValue(null,"handler");;
        handler.rejectedExecution(command, this);
    }

    public int runStateOf(int c)     { return c & ~CAPACITY; }

    boolean isRunning(int c) {
        return c < SHUTDOWN;
    }


    private boolean compareAndIncrementWorkerCount(int expect) {
        AtomicInteger ctl=getCtl();
        return ctl.compareAndSet(expect, expect + 1);
    }

    public Object getInstance(Object instance,String className,Object object) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException {

        Class enclosingClass = Class.forName(className);
        Constructor constructor = enclosingClass.getDeclaredConstructors()[0];

        constructor.setAccessible(true);
        return  constructor.newInstance(instance,object);
    }
    public  Object getPrivateValue(Object obj ,String propName) {
        Object value = null;
        try {

            // 通过属性获取对象的属性
            //.getDeclaredFields() 获得某个类的所有声明的字段,即包括public、private和proteced但不包括父类申明字段
            //.getClass() 是?个对象实例的?法,只有对象实例才有这个?法,具体的类是没有的

            Field field = obj.getClass().getDeclaredField(propName);
            // 对象的属性的访问权限设置为可访问
            //允许获取实体类private的参数信息
            field.setAccessible(true);
            // 获取属性的对应的值
            value = field.get(obj);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString());
            return null;
        }
        return value;
    }

    public boolean addWorker(Runnable firstTask, boolean core) {
        log.info("addWorker-1="+System.currentTimeMillis());

        retry:
        for (;;) {
            AtomicInteger ctl=getCtl();
            int c = ctl.get();
            int rs = runStateOf(c);

            BlockingQueue workQueue= (BlockingQueue) getPrivateValue(null,"workQueue");

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&
                    ! (rs == SHUTDOWN &&
                            firstTask == null &&
                            ! workQueue.isEmpty()))
                return false;
            log.info("addWorker-retry-1="+System.currentTimeMillis());
            for (;;) {
                log.info("addWorker-retry-2="+System.currentTimeMillis());
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                        wc >= (core ? getCorePoolSize() : getMaximumPoolSize()))
                    return false;
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }

        log.info("addWorker-Worker-="+System.currentTimeMillis());
        boolean workerStarted = false;
        boolean workerAdded = false;
       // Worker w = null;
        Object w=null;
        try {
           // w = new Worker(firstTask);

            w = getInstance(getThreadPool(),"java.util.concurrent.ThreadPoolExecutor$Worker",firstTask);

            //final Thread t = w.thread;
            final Thread t =  (Thread)getPrivateValue(w,"thread");

            log.info("addWorker-t-="+System.currentTimeMillis());
            if (t != null) {
                ReentrantLock mainLock11= (ReentrantLock) getPrivateValue(null,"mainLock");
                final ReentrantLock mainLock = mainLock11;
                log.info("addWorker-lock-="+System.currentTimeMillis());
                mainLock.lock();
                try {
                    // Recheck while holding lock.
                    // Back out on ThreadFactory failure or if
                    // shut down before lock acquired.
                    AtomicInteger ctl=getCtl();
                    int rs = runStateOf(ctl.get());

                    if (rs < SHUTDOWN ||
                            (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();

                        HashSet workers= (HashSet) getPrivateValue(null,"workers");
                        workers.add(w);

                        int s = workers.size();
                        if (s > getLargestPoolSize()){
                           // largestPoolSize = s;
                            setPrivateValue(null,"largestPoolSize",s);
                        }

                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                log.info("addWorker-workerAdded="+workerAdded+"   "+System.currentTimeMillis());
                if (workerAdded) {
                    log.info("addWorker-t.start()= start before 状态="+t.getState()+"  优先级别="+t.getPriority()+"  "+System.currentTimeMillis());

                    t.start();
                    log.info("addWorker-t.start()= start after 状态="+t.getState()+"  优先级别="+t.getPriority()+"  "+System.currentTimeMillis());

                    workerStarted = true;
                }
            }
        } catch (InstantiationException e) {
            log.error(e.toString());
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            log.error(e.toString());
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            log.error(e.toString());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            log.error(e.toString());
            e.printStackTrace();
        } finally {
            if (! workerStarted)
            {
                log.info("!workerStarted-t-="+System.currentTimeMillis());
                // addWorkerFailed(w);
                getPrivateMethodValue(getThreadPool(),"addWorkerFailed",w);

            }

        }
        return workerStarted;
    }

    

    private void decrementWorkerCount() {
        do {} while (! compareAndDecrementWorkerCount(getCtl().get()));
    }
    private boolean compareAndDecrementWorkerCount(int expect) {
        return getCtl().compareAndSet(expect, expect - 1);
    }

    public AtomicInteger getCtl() {

        /*if(executorServer==null){
            // executorServer = JzPreCheckUtil.getThreadPool();
            executorServer   = getThreadPool();
        }*/
        AtomicInteger ctl= (AtomicInteger) getPrivateValue(getThreadPool(),"ctl");
        return ctl;
    }



    int workerCountOf(int c)  { return c & CAPACITY; }


    public  Object getPrivateValue(ThreadPoolExecutor executorServer ,String propName) {
        Object value = null;
        try {
            if(executorServer==null){

                // executorServer = JzPreCheckUtil.getThreadPool();
                executorServer = getThreadPool();
            }
            // 通过属性获取对象的属性
            //.getDeclaredFields() 获得某个类的所有声明的字段,即包括public、private和proteced但不包括父类申明字段
            //.getClass() 是?个对象实例的?法,只有对象实例才有这个?法,具体的类是没有的

            Field field = executorServer.getClass().getSuperclass().getDeclaredField(propName);
            // 对象的属性的访问权限设置为可访问
            //允许获取实体类private的参数信息
            field.setAccessible(true);
            // 获取属性的对应的值
            value = field.get(executorServer);
        } catch (Exception e) {
            log.error(e.toString());
            e.printStackTrace();
            return null;
        }
        return value;
    }


    public  void setPrivateValue(ThreadPoolExecutor executorServer, String propName,Object value) {

        try {
            if(executorServer==null){
                // executorServer = JzPreCheckUtil.getThreadPool();
                executorServer = getThreadPool();
            }
            // 通过属性获取对象的属性
            //.getDeclaredFields() 获得某个类的所有声明的字段,即包括public、private和proteced但不包括父类申明字段
            //.getClass() 是?个对象实例的?法,只有对象实例才有这个?法,具体的类是没有的
            Field field = executorServer.getClass().getSuperclass().getDeclaredField(propName);
            // 对象的属性的访问权限设置为可访问
            //允许获取实体类private的参数信息
            field.setAccessible(true);
            // 获取属性的对应的值
            field.set(executorServer,value);

        } catch (Exception e) {
            log.error(e.toString());
            e.printStackTrace();

        }
    }


    

    public Object getPrivateMethodValue(Object obj, String propName,Object val) {
        //Object value = null;
        try {
            Class c = obj.getClass().getSuperclass();

            // https://blog.csdn.net/qq_34626094/article/details/122687833
            //getDeclaredMethod java.lang.NoSuchMethodException的异常原因在于调用getDeclaredMethod时要同时指定方法名和参数名,这两个不能错误。
            Method method = c.getDeclaredMethod(propName,val.getClass());
            method.setAccessible(true);
            Object[] values = new Object[1];
            values[0] = val;
            return method.invoke(obj,values);
        } catch (Exception e) {
            log.error(e.toString());
            return null;
        }
    }
}

你可能感兴趣的:(java)