线程池

三大方法

// Executors 工具类: 3大方法
// 使用了线程池之后,使用线程池来创建线程
public class Demo01 {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程
//        ExecutorService threadPool = Executors.newFixedThreadPool(5);//创建一个固定大小的线程池
//        ExecutorService threadPool = Executors.newCachedThreadPool();//可伸缩的,遇强则强,遇弱则弱

        try {
            for (int i = 0; i < 100; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + " ok");
                });
            }
        } finally {
            // 线程池用完,程序技术,关闭线程池
            threadPool.shutdown();
        }
    }
}

七大参数

源码分析

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

本质: ThreadPoolExecutor()

代码实现

public ThreadPoolExecutor(int corePoolSize,//核心线程池大小
                          int maximumPoolSize,//最大核心线程池大小
                          long keepAliveTime,//超时了 没有人调用就会被释放
                          TimeUnit unit,// 超时单位
                          BlockingQueue<Runnable> workQueue,//阻塞队列
                          ThreadFactory threadFactory,//线程工厂:创建线程的,一般不用动
                          RejectedExecutionHandler handler//拒绝策略) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.acc = System.getSecurityManager() == null ?
            null :
            AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

4种拒绝策略

手动创建线程池

/*
new ThreadPoolExecutor.AbortPolicy() //队列满了,还有线程进来,不处理,抛出异常
new ThreadPoolExecutor.CallerRunsPolicy() //哪来的去哪里
new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常
new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和最早的竞争,也不会抛出异常
 */
public class Demo01 {
    public static void main(String[] args) {
        // 自定义线程池! 工作 ThreadPoolExecutor
        ExecutorService threadPool = new ThreadPoolExecutor(
                2, 5,
                3, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());

        try {
            // 最大承载: Queue + max
            // 超过 java.util.concurrent.RejectedExecutionException
            for (int i = 0; i < 9; i++) {
                final int temp = i;
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + " " + temp);
                });
            }
        } finally {
            // 线程池用完,程序技术,关闭线程池
            threadPool.shutdown();
        }
    }
}

IO密集型和CPU密集型

调优
池的大小该如何设置?

public class Demo01 {
    public static void main(String[] args) {
        // 自定义线程池! 工作 ThreadPoolExecutor

        // 最大线程到底该如何定义
        // 1.CPU密集型,几核,就是几,可以保证cpu的效率最高!
        // 2.IO密集型, > 2*判断你的程序中十分耗IO的线程
        // 程序 15个大型任务 io十分占用资源!

        // 获取cpu的核数
        System.out.println(Runtime.getRuntime().availableProcessors());

        ExecutorService threadPool = new ThreadPoolExecutor(
                2, Runtime.getRuntime().availableProcessors(),
                3, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());
        try {
            // 最大承载: Queue + max
            // 超过 java.util.concurrent.RejectedExecutionException
            for (int i = 0; i < 9; i++) {
                final int temp = i;
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + " " + temp);
                });
            }
        } finally {
            // 线程池用完,程序技术,关闭线程池
            threadPool.shutdown();
        }
    }
}
posted @   不写代码想写诗的虫子  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示