十:线程与线程池(四)---线程池

线程池

线程池线程池作用
fixed固定大小线程池,启动时建立线程,不关闭,一直持有
cached缓存线程池,空闲一分钟自动删除,需要时重建
limited可伸缩线程池,但池中的线程数只会增加不会收缩
eager优先创建Worker线程池

线程配置

fixed: <dubbo:protocol name=“dubbo” port=“29014” dispatcher=“all” threadpool=“fixed” threadname=“jangzheng” threads=“200” queues=“0”/>
limited: <dubbo:protocol name=“dubbo” port=“29014” dispatcher=“all” threadpool=“limited” threadname=“jangzheng” corethreads=“10” threads=“200” queues=“0”/>
cached:<dubbo:protocol name=“dubbo” port=“29014” dispatcher=“all” threadpool=“cached” threadname=“jangzheng” corethreads=“10” threads=“200” queues=“0” alive=“60000”/>
eager:<dubbo:protocol name=“dubbo” port=“29014” dispatcher=“all” threadpool=“eager” threadname=“jangzheng” corethreads=“10” threads=“200” queues=“0” alive=“60000”/>

代码分析

FixedThreadPool

 */
 //org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool
public class FixedThreadPool implements ThreadPool {

    @Override
    public Executor getExecutor(URL url) {
        String name = url.getParameter(THREAD_NAME_KEY, DEFAULT_THREAD_NAME);
        int threads = url.getParameter(THREADS_KEY, DEFAULT_THREADS);
        int queues = url.getParameter(QUEUES_KEY, DEFAULT_QUEUES);
        return new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS,
                queues == 0 ? new SynchronousQueue<Runnable>() :
                        (queues < 0 ? new LinkedBlockingQueue<Runnable>()
                                : new LinkedBlockingQueue<Runnable>(queues)),
                new NamedInternalThreadFactory(name, true), new AbortPolicyWithReport(name, url));
    }

}

LimitedThreadPool

//org.apache.dubbo.common.threadpool.support.limited.LimitedThreadPool
public class LimitedThreadPool implements ThreadPool {

    @Override
    public Executor getExecutor(URL url) {
        String name = url.getParameter(THREAD_NAME_KEY, DEFAULT_THREAD_NAME);
        int cores = url.getParameter(CORE_THREADS_KEY, DEFAULT_CORE_THREADS);
        int threads = url.getParameter(THREADS_KEY, DEFAULT_THREADS);
        int queues = url.getParameter(QUEUES_KEY, DEFAULT_QUEUES);
        return new ThreadPoolExecutor(cores, threads, Long.MAX_VALUE, TimeUnit.MILLISECONDS,
                queues == 0 ? new SynchronousQueue<Runnable>() :
                        (queues < 0 ? new LinkedBlockingQueue<Runnable>()
                                : new LinkedBlockingQueue<Runnable>(queues)),
                new NamedInternalThreadFactory(name, true), new AbortPolicyWithReport(name, url));
    }

}

CachedThreadPool

//org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool
public class CachedThreadPool implements ThreadPool {

    @Override
    public Executor getExecutor(URL url) {
        String name = url.getParameter(THREAD_NAME_KEY, DEFAULT_THREAD_NAME);
        int cores = url.getParameter(CORE_THREADS_KEY, DEFAULT_CORE_THREADS);
        int threads = url.getParameter(THREADS_KEY, Integer.MAX_VALUE);
        int queues = url.getParameter(QUEUES_KEY, DEFAULT_QUEUES);
        int alive = url.getParameter(ALIVE_KEY, DEFAULT_ALIVE);
        return new ThreadPoolExecutor(cores, threads, alive, TimeUnit.MILLISECONDS,
                queues == 0 ? new SynchronousQueue<Runnable>() :
                        (queues < 0 ? new LinkedBlockingQueue<Runnable>()
                                : new LinkedBlockingQueue<Runnable>(queues)),
                new NamedInternalThreadFactory(name, true), new AbortPolicyWithReport(name, url));
    }
}

EagerThreadPool

//org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool
public class EagerThreadPool implements ThreadPool {

    @Override
    public Executor getExecutor(URL url) {
        String name = url.getParameter(THREAD_NAME_KEY, DEFAULT_THREAD_NAME);
        int cores = url.getParameter(CORE_THREADS_KEY, DEFAULT_CORE_THREADS);
        int threads = url.getParameter(THREADS_KEY, Integer.MAX_VALUE);
        int queues = url.getParameter(QUEUES_KEY, DEFAULT_QUEUES);
        int alive = url.getParameter(ALIVE_KEY, DEFAULT_ALIVE);

        // init queue and executor
        TaskQueue<Runnable> taskQueue = new TaskQueue<Runnable>(queues <= 0 ? 1 : queues);
        EagerThreadPoolExecutor executor = new EagerThreadPoolExecutor(cores,
                threads,
                alive,
                TimeUnit.MILLISECONDS,
                taskQueue,
                new NamedInternalThreadFactory(name, true),
                new AbortPolicyWithReport(name, url));
        taskQueue.setExecutor(executor);
        return executor;
    }
}

引入时机

我们假设为All的线程模型,进入AllChannelHandler类中

    //org.apache.dubbo.remoting.transport.dispatcher.all.AllChannelHandler#connected
    @Override
    public void connected(Channel channel) throws RemotingException {
    	//进入此方法,获取线程池
        ExecutorService executor = getExecutorService();
        try {
            executor.execute(new ChannelEventRunnable(channel, handler, ChannelState.CONNECTED));
        } catch (Throwable t) {
            throw new ExecutionException("connect event", channel, getClass() + " error when process connected event .", t);
        }
    }
    //org.apache.dubbo.remoting.transport.dispatcher.WrappedChannelHandler#getExecutorService
    @Deprecated
    public ExecutorService getExecutorService() {
        //进入此方法
        return getSharedExecutorService();
    }
    
    //继续调用
    public ExecutorService getSharedExecutorService() {
        ExecutorRepository executorRepository =
                //此处ExecutorRepository需要关注下
                ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
        
        ExecutorService executor = executorRepository.getExecutor(url);
        if (executor == null) {
        	//通过url获取对应的线程池,我们此方法
            executor = executorRepository.createExecutorIfAbsent(url);
        }
        return executor;
    }
    //org.apache.dubbo.common.threadpool.manager.DefaultExecutorRepository#createExecutorIfAbsent
    public synchronized ExecutorService createExecutorIfAbsent(URL url) {
        String componentKey = EXECUTOR_SERVICE_COMPONENT_KEY;
        if (CONSUMER_SIDE.equalsIgnoreCase(url.getSide())) {
            componentKey = CONSUMER_SIDE;
        }
        Map<Integer, ExecutorService> executors = data.computeIfAbsent(componentKey, k -> new ConcurrentHashMap<>());
        Integer portKey = url.getPort();
        //调用createExecutor(url),创建线程池,我们看下
        ExecutorService executor = executors.computeIfAbsent(portKey, k -> createExecutor(url));
        // If executor has been shut down, create a new one
        if (executor.isShutdown() || executor.isTerminated()) {
            executors.remove(portKey);
            executor = createExecutor(url);
            executors.put(portKey, executor);
        }
        return executor;
    }
    //org.apache.dubbo.common.threadpool.manager.DefaultExecutorRepository#createExecutor
    private ExecutorService createExecutor(URL url) {
        return (ExecutorService) 
        //创建指定的线程池,如果没有指定的话,默认使用fixed
        ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url);
    }
//org.apache.dubbo.common.threadpool.ThreadPool


@SPI("fixed")
public interface ThreadPool {

    /**
     * Thread pool
     *
     * @param url URL contains thread parameter
     * @return thread pool
     */
    @Adaptive({THREADPOOL_KEY})  //THREADPOOL_KEY = "threadpool";
    Executor getExecutor(URL url);

}

线程数设置

QPS = 100 (每秒100个请求)
tp99 = 100ms (每个请求处理时间是100毫秒)
threads = QPS * tp99 / 1000 (QPS 乘上tp99得到每个请求处理的时间,除以1000 转为秒)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值