10万级的ThreadPoolExecutor线程池的配置
ThreadPoolExecutor线程池的一些基本知识,创建
ThreadPoolExecutor对象,这个对象是管理线程池的
下面是工作流程,看图容易理解,所以可以看到 核心线程池跟队列都满了,最大线程池没满的话就是创建新的线程,最大的都满了,则会执行饱和策略。基本是什么没满用什么
饱和策略
还有一个自定义的策略,这个有很多资料
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
while (e.getQueue().remainingCapacity() == 0);
e.execute(r);
}
}
remainingCapacity接口,主线程只要不断获取空余个数,是0就继续获取,直到不是0为止,这个方法不错。
我测试了10万级最快是3秒,如果一个线程执行完任务需要一秒,则10万级会是1分30秒。
/** * @Description:线程池管理类 * @Author: chen * @CreateDate: 2018/7/31 16:15 * @UpdateDate: 2018/7/31 16:15 **/ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class MyThreadPoolManager { /** * 说明:下面这些常量是根据AsyncTask的源码配置的,大家可以根据自己需求自行配置 */ //根据cpu的数量动态的配置核心线程数和最大线程数 private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); //核心线程数 = CPU核心数 + 1 private static final int CORE_POOL_SIZE = CPU_COUNT + 1050; //线程池最大线程数 = CPU核心数 * 2 + 1 private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 100000; //非核心线程闲置时间 = 超时1s private static final int KEEP_ALIVE = 1; // 要确保该类只有一个实例对象,避免产生过多对象消费资源,所以采用单例模式 private MyThreadPoolManager() { } private static MyThreadPoolManager sInstance; public synchronized static MyThreadPoolManager getsInstance() { if (sInstance == null) { sInstance = new MyThreadPoolManager(); } return sInstance; } // 线程池的对象 private ThreadPoolExecutor executor; // 使用线程池,线程池中线程的创建完全是由线程池自己来维护的,我们不需要创建任何的线程 // 我们所需要做的事情就是往这个池子里面丢一个又一个的任务 public void execute(Runnable r) { if (executor == null) { /** * corePoolSize:核心线程数 * maximumPoolSize:线程池所容纳最大线程数(workQueue队列满了之后才开启) * keepAliveTime:非核心线程闲置时间超时时长 * unit:keepAliveTime的单位 * workQueue:等待队列,存储还未执行的任务 * threadFactory:线程创建的工厂 * handler:异常处理机制 */ executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy()); } try { executor.execute(r);// 把一个任务丢到了线程池中 } catch (Exception e) { e.printStackTrace(); } } public void cancel(Runnable r) { if (r != null) { executor.getQueue().remove(r);//把任务移除等待队列 } } }
然后是线程类
/** * @Description:线程类 * @Author: chen * @CreateDate: 2018/7/31 16:28 * @UpdateDate: 2018/7/31 16:28 **/ public class MyThread implements Runnable{ public void run() { long time = System.currentTimeMillis(); System.out.println("开始启动线程 ssss"+ Thread.currentThread().getId()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getId()+" 线程结束 dddd time:"+(System.currentTimeMillis()-time)); } }
再然后是测试类
/** * @Description:测试类 * @Author: chen * @CreateDate: 2018/7/25 11:20 * @UpdateDate: 2018/7/25 11:20 **/ public class Atest { @Test public void te()throws Exception { System.out.println(Thread.currentThread().getId()+" 2222222 enter time:" + System.currentTimeMillis()); MyThreadPoolManager myThreadPoolManager=MyThreadPoolManager.getsInstance(); for (int i=0;i<100000;i++){ MyThread myThread=new MyThread(); myThreadPoolManager.execute(myThread); } System.out.println("3333leave time:" + System.currentTimeMillis()); Thread.sleep(100000); // 因为junit结束会结束jvm,所以让它等会异步线程 } }
所以觉得好用的话就留个好评吧,评论好少,,,,,