• Java线程池的使用示例及注意事项


    创建线程的代价是昂贵的,还会给GC带来压力,如果频繁创建线程那么GC的时候也需要回收对应的线程资源。使用线程池,一方面可以提升线程的使用率,减少对象的创建、销毁;另外,线程池还可以有效控制线程数,提升服务器的使用资源,避免因线程使用不当导致资源不足而发生宕机等问题。

    示例代码如下:

         public static final String THREAD_NAME_PREFIX = "listen-async-send-thread-";
         private static final ThreadPoolExecutor executor =
                 new ThreadPoolExecutor(4, 32, 10, TimeUnit.MINUTES,
                         new LinkedBlockingQueue<Runnable>(10000),
                         new ThreadFactory() {
                             private AtomicInteger id = new AtomicInteger(0);
    
                             @Override
                             public Thread newThread(Runnable r) {
                                 Thread thread = new Thread(r);
                                 thread.setName(THREAD_NAME_PREFIX + id.addAndGet(1));
                                 return thread;
                             }
                         }, new ThreadPoolExecutor.CallerRunsPolicy());
    
    
         public void listen(HibernateChangeEntity changeEntity) {
            
             executor.execute(new Runnable() {
                 @Override
                 public void run() {
                     try {
                         if (Thread.currentThread().getName().startsWith(THREAD_NAME_PREFIX)) {
                             // 构造线程上下文
    
                         }
    
                        // 业务代码部分
    
                    } catch (Throwable e) {
    
                    } finally {
                         if (Thread.currentThread().getName().startsWith(THREAD_NAME_PREFIX)) {
                             // 清理线程上下文的信息
    
                         }
                     }
                 }
             });
        }

    建议及注意事项:

    1、设定线程名的统一前缀,便于跟踪查看及问题排查

    2、合适的初始线程数、最大线程数及任务队列容量(只有超过队列容量,池才会在coreSize基础上创建新的线程)

    3、设置及清理线程上下文等信息(因为线程会被复用,如果不进行清理,会影响后续业务逻辑和造成内存泄露等问题)

    4、捕捉所有异常并做按需处理

    5、ThreadPoolExecutor执行顺序

    1. 当线程数小于核心线程数时,创建线程。
    2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
    3. 当线程数大于等于核心线程数,且任务队列已满
      1. 若线程数小于最大线程数,创建线程
      2. 若线程数等于最大线程数,拒绝任务,触发rejectedExecutionHandler对应的策略

    6、线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常

    ThreadPoolExecutor类有几个内部实现类来处理这类情况:
    1、AbortPolicy 丢弃任务,抛运行时异常
    2、CallerRunsPolicy 回到主线程执行任务
    3、DiscardPolicy 忽视,什么都不会发生
    4、DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务

    另外,就是实现RejectedExecutionHandler接口,可自定义处理器

    参考资料:

    https://blog.csdn.net/qq_23000805/article/details/89208561 

  • 相关阅读:
    图论算法——最短路系列
    1126 数字统计 2010年NOIP全国联赛普及组
    JavaEE Tutorials (10)
    情书
    洛谷 P1171 售货员的难题
    洛谷 P1769 淘汰赛制_NOI导刊2010提高(01)
    洛谷 P1858 多人背包
    HDU 2639 Bone Collector II
    国庆 day 6 下午
    国庆 day 6 上午
  • 原文地址:https://www.cnblogs.com/zhaoguan_wang/p/15996601.html
Copyright © 2020-2023  润新知