线程池

Posted fengchuxiaodai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池相关的知识,希望对你有一定的参考价值。

 ThreadPoolExecutor executor = new ThreadPoolExecutor(2, //核心线程数
         5,//最大线程数
         60L, //临时线程空闲时间
         TimeUnit.SECONDS,//时间单位
         new ArrayBlockingQueue<Runnable>(25), //线程池任务队列
         new ThreadPoolExecutor.CallerRunsPolicy());//任务超出线程池能力异常处理

线程池手动创建方法如上所示,

核心线程数表示当线程池有任务进来时,会创建线程处理任务,最大不能超过这个数值,并且空闲时不会被释放;

最大线程数表示当核心线程数被占用,并且队列任务装满之后,会临时开启线程来处理后续加入的任务,临时线程最大数量 =  最大线程数-核心线程数;

临时线程空闲时间表示临时线程最大空闲时间,超过这个时间后,临时线程会释放

线程池任务队列表示当核心线程都被占用时,后续任务会被添加进队列中等待,等核心进程空闲时,会拿取队列中的任务进行处理。当队列装满后,会创建临时线程处理任务。

异常处理作用是当线程池任务队列装满,并且最大线程数创建满且都在执行任务,后续再有任务进来时,线程池会将任务交给异常处理消化

 

 

 

当需要线程池处理完事件,再回到主线程执行是,可以使用CountDownLatch让主线程阻塞,当CountDownLatch配置的任务数执行完成后,主线程再被唤醒

public static void test(boolean flag) {
    System.out.println("开启线程池");
    ThreadPoolExecutor executor = new ThreadPoolExecutor(5, //活动线程数
            5,//最大线程数
            60L, //临时线程空闲时间
            TimeUnit.SECONDS,//时间单位
            new ArrayBlockingQueue<>(30), //线程池任务队列
            new ThreadPoolExecutor.CallerRunsPolicy());//任务超出线程池能力异常处理
    executor.allowCoreThreadTimeOut(true);
    int forCounts = 30;
    CountDownLatch countd = new CountDownLatch(forCounts);// 线程池优先执行的计时器
    syncSubmit1(executor, countd, forCounts);
    try {
        countd.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    syso(Thread.currentThread().getName());
    //优雅释放线程池,等待线程池中正在执行任务的线程执行完后再进行释放
    executor.shutdownNow();
    //强制释放线程池,所有线程(包含正在执行任务的线程)立即停止并释放
    //executor.shutdown();
    while (true) {
        if (executor.isShutdown()) {
            syso("线程池释放了");
            System.exit(0);
        } else {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            syso("线程池没有释放");
        }
    }
}

private static void syncSubmit1(ThreadPoolExecutor executor, CountDownLatch countd, int forCounts) {
    for (int i = 0; i < forCounts; i++) {
        executor.submit(new MyThread1(i, countd));
    }
}

 static class MyThread1 implements Runnable {
     int            i;
     CountDownLatch countd;
     public MyThread1(int i, CountDownLatch countd) {
         this.i = i;
         this.countd = countd;
     }
     @Override
     public void run() {
         if (countd.getCount() != 0) {
             syso(" i = " + i + ",ThreadPoolExecutor‘run‘s thread name = " + Thread.currentThread().getName());
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         countd.countDown();
     }
 }

  

 

代码执行结果:

开启线程池
 i = 1,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-2
 i = 0,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-1
 i = 2,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-3
 i = 3,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-4
 i = 4,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-5
 i = 5,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-1
 i = 8,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-5
 i = 7,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-2
 i = 6,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-3
 i = 9,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-4
 i = 10,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-2
 i = 14,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-4
 i = 11,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-1
 i = 13,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-3
 i = 12,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-5
 i = 15,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-4
 i = 19,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-1
 i = 18,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-3
 i = 16,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-5
 i = 17,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-2
 i = 20,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-2
 i = 24,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-1
 i = 23,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-3
 i = 22,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-5
 i = 21,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-4
 i = 25,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-5
 i = 27,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-1
 i = 28,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-2
 i = 29,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-4
 i = 26,ThreadPoolExecutor‘run‘s thread name = pool-1-thread-3
main
线程池释放了

  

以上是线程池的基本使用,还有很多其他用法,慢慢研究吧

以上是关于线程池的主要内容,如果未能解决你的问题,请参考以下文章

Java——线程池

Motan在服务provider端用于处理request的线程池

Java线程池详解

Java线程池详解

Java 线程池详解

线程池-实现一个取消选项