All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.core.lang.thread.DefaultPartitionThreadExecutor Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
/*
 * Copyright (C) 2008 feilong
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.feilong.core.lang.thread;

import static com.feilong.core.util.CollectionsUtil.partition;

import java.util.List;
import java.util.Map;

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

import com.feilong.core.Validate;
import com.feilong.core.lang.ThreadUtil;
import com.feilong.core.util.CollectionsUtil;
import com.feilong.tools.slf4j.Slf4jUtil;

/**
 * 默认基于 {@link Thread} 数组的执行实现.
 *
 * @author feilong
 * @since 1.11.0
 * @since 2.0.0 move from package com.feilong.core.lang
 */
public class DefaultPartitionThreadExecutor extends AbstractPartitionThreadExecutor{

    /** The Constant LOGGER. */
    private static final Logger                 LOGGER   = LoggerFactory.getLogger(DefaultPartitionThreadExecutor.class);

    //---------------------------------------------------------------

    /** Static instance. */
    public static final PartitionThreadExecutor INSTANCE = new DefaultPartitionThreadExecutor();

    //---------------------------------------------------------------

    /**
     * Actual execute.
     *
     * @param 
     *            the generic type
     * @param list
     *            the list
     * @param eachSize
     *            the each size
     * @param paramsMap
     *            the params map
     * @param partitionRunnableBuilder
     *            the partition runnable builder
     */
    @Override
    protected  void actualExecute(
                    List list,
                    int eachSize,
                    Map paramsMap,
                    PartitionRunnableBuilder partitionRunnableBuilder){
        //1. 自动构造需要启动的线程数组
        Thread[] threads = buildThreadArray(list, eachSize, paramsMap, partitionRunnableBuilder);

        //2. start 并且 join
        ThreadUtil.startAndJoin(threads);
    }

    //---------------------------------------------------------------

    /**
     * Builds the thread array.
     * 
     * 

* 调用 {@link CollectionsUtil#partition(List, int)} 对list 分成N份,对应的创建N份线程,每个线程的 名字 参见 * {@link #buildThreadName(int, PartitionRunnableBuilder)} *

* *

* 会自动创建 ThreadGroup,线程组名字参见 {@link #buildThreadGroupName(List, PartitionRunnableBuilder)},
* 所有新建的线程将归属到该 线程组,你可以在自定义的partitionRunnableBuilder中监控或者管理 该ThreadGroup *

* * @param * the generic type * @param list * the list * @param eachSize * the per size * @param paramsMap * the params map * @param partitionRunnableBuilder * the group runnable builder * @return the thread[] */ private static Thread[] buildThreadArray( List list, int eachSize, Map paramsMap, PartitionRunnableBuilder partitionRunnableBuilder){ //使用group进行管理 ThreadGroup threadGroup = new ThreadGroup(buildThreadGroupName(list, partitionRunnableBuilder)); //将 list 分成 N 份 List> groupList = partition(list, eachSize); //------------------------------------------------------------------- int i = 0; Thread[] threads = new Thread[groupList.size()]; for (List perBatchList : groupList){ String threadName = buildThreadName(i, partitionRunnableBuilder); PartitionThreadEntity partitionThreadEntity = new PartitionThreadEntity( threadName, list.size(), eachSize, i, perBatchList.size()); Runnable runnable = partitionRunnableBuilder.build(perBatchList, partitionThreadEntity, paramsMap); threads[i] = new Thread(threadGroup, runnable, threadName); i++; } //--------------------------------------------------------------- LOGGER.info("total list size:[{}],build [{}] threads,perSize:[{}]", list.size(), threads.length, eachSize); return threads; } //--------------------------------------------------------------- /** * 构建线程组名称. * *

格式:

* *
* "ThreadGroup-partitionRunnableBuilder 实现类名称-list size" *
* * @param * the generic type * @param list * the list * @param partitionRunnableBuilder * the group runnable builder * @return the string */ private static String buildThreadGroupName(List list,PartitionRunnableBuilder partitionRunnableBuilder){ Validate.notNull(partitionRunnableBuilder, "partitionRunnableBuilder can't be null!"); return Slf4jUtil.format("ThreadGroup-{}-{}", getName(partitionRunnableBuilder), list.size()); } /** * 构建线程名称. * *

格式:

* *
* "Thread-partitionRunnableBuilder 实现类名称-{@link com.feilong.core.lang.PartitionThreadEntity#getBatchNumber() batchNumber}" *
* *

作用:

* *
* *
    *
  • 一来便于管理, 可以使用相关代码来获得线程;
  • *
  • 二来常用于日志显示, 比如, 如果是 log4j 的配置文件,如果 ConversionPattern * *
         * {@code 
         * 
         * }
         * 
    * * 其中 %t 表示 线程名称 * * 正常情况的日志,会显示(示例) * *
         * 13:54:43 Thread-NovelpartitionRunnableBuilder-13 INFO (NovelpartitionRunnableBuilder.java:91) 第914章 好手段 3406 [6/20] 14 30%
         * 13:54:43 Thread-NovelpartitionRunnableBuilder-5 INFO (NovelpartitionRunnableBuilder.java:91) 第761章 不得其时 3573 [7/20] 6 35%
         * 13:54:43 Thread-NovelpartitionRunnableBuilder-3 INFO (NovelpartitionRunnableBuilder.java:91) 第718章 各打各的算盘 3411 [4/20] 4 20%
         * 
    * * 如果代码有异常, 会显示 * *
         * 13:54:52 Thread-NovelpartitionRunnableBuilder-16 ERROR (DefaultChapterBuilder.java:83) Exception:
         * com.feilong.tools.jsoup.JsoupUtilException: urlString:[http://www.37zw.com/0/181/1662249.html],userAgent:[Mozilla/5.0 (X11; Linux
         * x86_64) AppleWebKit/535.21 (KHTML, like Gecko) Chrome/19.0.1042.0 Safari/535.21]
         * at com.feilong.tools.jsoup.JsoupUtil.getDocument(JsoupUtil.java:87)
         * at com.feilong.tools.jsoup.JsoupUtil.getDocument(JsoupUtil.java:65)
         * at com.feilong.project.novel.build.DefaultChapterBuilder.getContentElement(DefaultChapterBuilder.java:124)
         * at com.feilong.project.novel.build.DefaultChapterBuilder.build(DefaultChapterBuilder.java:68)
         * at com.feilong.project.novel.build.NovelpartitionRunnableBuilder$1.run(NovelpartitionRunnableBuilder.java:86)
         * at java.lang.Thread.run(Thread.java:745)
         * 
    * *
  • *
* *
* * @param * the generic type * @param batchNumber * the batch number * @param partitionRunnableBuilder * the group runnable builder * @return 如果 partitionRunnableBuilder 是null,抛出 {@link NullPointerException}
*/ private static String buildThreadName(int batchNumber,PartitionRunnableBuilder partitionRunnableBuilder){ Validate.notNull(partitionRunnableBuilder, "partitionRunnableBuilder can't be null!"); return Slf4jUtil.format("Thread-{}-{}", getName(partitionRunnableBuilder), batchNumber); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy