在工作中,用到了一个多线程模型,在此记录
业务需求:需要在每天上午对购物车对应表的残余记录做统计分析,将每条购物车记录的code发送到另一台管理的服务器,并且有注入电子类,家电类,日用品类等业务条线,如果有10个业务条线,单次过滤的数据约百万条,根据返回的code做逻辑处理。
设计思路:每个业务条线就是一个线程组,每个线程组独立一个线程池,能够分配不同的线程状态(根据每条业务条线分配合适的核心线程数、最大线程数、存活时间等)。
补充知识:
1.ThreadGroup的知识
我们知道如果使用自定义的线程池,比如如下代码
ThreadFactory threadFactory = new ThreadFactoryWithBusiName(new ThreadGroup(group, tc.getBusiName()), tc.getBusiName());
ThreadPoolExecutorWithBusiName threadPoolExecutorWithBusiName =
new ThreadPoolExecutorWithBusiName(tc.getBusiName(), tc.getMin(), tc.getMax(), tc.getKeepAliveTime(), TimeUnit.SECONDS, taskQueue, threadFactory, tc.getRejectHandler());
我们使用线程组的概念来进行真正意义上的线程分组,如果线程工厂不指定传入线程组的话,使用默认的线程组是无法完成线程的分组的
比如这样去分组
public static void main(String[] args) {
ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newCachedThreadPool();
final ThreadGroup group = new ThreadGroup("Main_Test_Group");
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(group, new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000 * 3);
System.out.println(Thread.currentThread().getName()+"执行完毕");
System.out.println("当前线程组中的运行线程数"+group.activeCount());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, group.getName()+" #"+i+"");
pool.execute(thread);
}
}
执行的结果
pool-2-thread-5执行完毕
pool-2-thread-4执行完毕
pool-2-thread-1执行完毕
pool-2-thread-2执行完毕
pool-2-thread-3执行完毕
当前线程组中的运行线程数0
当前线程组中的运行线程数0
当前线程组中的运行线程数0
当前线程组中的运行线程数0
当前线程组中的运行线程数0
执行的结果是线程组不会分组生效的,原因是虽然指定了线程的单个分组,但是newCacheThreadPool所使用的默认工厂的线程组是--系统线程组,所以是不生效的
线程工厂默认源码
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
n