线程池

线程池需要学
  • 三大方法
  • 七大参数
  • 四大拒绝策略
三大方法:
  1. Executors.newSingleThreadExecutor();
    1. 创建单个线程的线程池
  2. Executors.newFixedThreadPool(int count);
    1. 创建指定数量的线程的线程池
  3. Executors.newCachedThreadPool();
    1. 根据使用数量自动扩容的线程池

 //创建单个线程的线程池
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        //创建指定数量线程的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        //创建可变数量线程的线程池
        ExecutorService threadPool = Executors.newCachedThreadPool();
        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"   Running");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
创建三个对象,分别十次循环创建线程
Executors.newSingleThreadExecutor();

Executors.newFixedThreadPool(int count);

Executors.newCachedThreadPool();

七大参数

银行办理业务:柜台1 2号在办理业务,3 4 5 号暂停业务,所以最大线程数就是5个,核心线程数就是2个,候客区的三个就是阻塞队列,当还有人来,没有地方了,要么再等,要么离开,这就是拒绝策略。
  1. corePoolSize 核心线程数
  2. maximumPoolSize 最大线程数
  3. keepAliveTime 当线程大于最大线程数,则会根据超时时间进行活性检查,一旦超过时间便销毁线程
  4. TimeUnit 超时单位
  5. BlockingQueue<Runnable> 阻塞队列
  6. ThreadFactory 线程工厂,创建线程的
  7. RejectedExecutionHandler 拒绝策略
我们使用线程池,一定不要使用Executors创建,我们要自定义线程池。

创建线程池eg:
ExecutorService threadPool = new ThreadPoolExecutor(
        3,                      //核心线程数
        5,                 //最大线程数
        2,          //超时时间,当线程大于最大线程数,则会根据超时时间进行活性检查,
                   // 一旦超过时间便销毁线程
        TimeUnit.SECONDS,       //超时时间单位
        new ArrayBlockingQueue<>(3),//阻塞队列
        Executors.defaultThreadFactory(),   //线程工厂
        new ThreadPoolExecutor.AbortPolicy() //拒绝策略
        );
最大线程承载:maximumPoolSize+BlockingQueue
一旦超过了最大承载,便会被拒绝策略接收
四大拒绝策略:
  1. new ThreadPoolExecutor.Abortpolicy()
    1. 超过最大承载,则会抛出异常
  2. new ThreadPoolExecutor.CallerRunsPolicy()
    1. 交给主线程处理,不抛出异常
  3. new ThreadExecutor.DiscardPolicy()
    1. 队列满了,不会抛出异常,丢弃被拒绝的任务
  4. new ThreadExecutor.DiscardOldestPolicy()
    1. 队列满了,尝试和最开始的线程竞争,不抛出异常
package com.xiaofei.pool;

import java.util.concurrent.*;

/**
 * @author xiaofei
 * @version 1.0
 * @date 2020/9/10 18:19
 */

public class ThreadPoolTest {
    public static void main(String[] args) {
//        ExecutorService threadPool = Executors.newSingleThreadExecutor();
//        ExecutorService threadPool = Executors.newFixedThreadPool(5);
//        ExecutorService threadPool = Executors.newCachedThreadPool();
        ExecutorService threadPool = new ThreadPoolExecutor(
                3,                      //核心线程数
                5,                 //最大线程数
                2,                    //当线程大于最大线程数,则会根据超时时间进行活性检查,
                                                    // 一旦超过时间便销毁线程
                TimeUnit.SECONDS,                   //超时时间单位
                new ArrayBlockingQueue<>(3),//阻塞队列
                Executors.defaultThreadFactory(),   //线程工厂
                new ThreadPoolExecutor.DiscardOldestPolicy()
//                new ThreadPoolExecutor.DiscardPolicy()
//                new ThreadPoolExecutor.CallerRunsPolicy()
//                new ThreadPoolExecutor.AbortPolicy() //拒绝策略
                );
        try {
            for (int i = 0; i < 9; i++) {
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"   Running");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}
如何判断最大线程数?
  1. CPU密集型
    1. 查看cpu是几核的,根据核数判断最大线程数
    2. Runtime.getRuntime().availableProcessors();
  2. IO密集型
    1. 通过查看有多少个十分耗IO的线程,一般最大值设置为其两倍
package com.xiaofei.pool;

import java.util.concurrent.*;

/**
 * @author xiaofei
 * @version 1.0
 * @date 2020/9/11 13:00
 */

public class ThreadPool2 {
    public static void main(String[] args) {
        //获取电脑的核数
        final int MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors();
        ExecutorService threadPool = new ThreadPoolExecutor(
                3,
                MAX_POOL_SIZE,
                3,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy()
        );
        try {
            for (int i = 0; i < (MAX_POOL_SIZE + 3); i++) {
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"   Running");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

原文地址:https://www.cnblogs.com/xiexiaofei/p/14156003.html