Java线程池练习

ThreadPoolExercise1

java 复制代码
package ThreadPoolExercise20240813;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExercise1 {
    public static void main(String[] args) throws InterruptedException {
        // 线程池
        // 线程池,顾名思义,就像一个水池,水池中存储了大量的水;而线程池中可以存储大量的线程

    /* 线程池的意义:
       系统创建一个线程的成本相对较高,其涉及到与操作系统的交互,当程序中需要创建大量生命周期短暂的线程时
       频繁的创建和销毁线程对于系统的资源是极大的消耗,甚至可能大于业务本身对于资源的消耗。所以说针对这种大量创建线程的
       情况,就可以使用线程池------------线程池在启动时就会创建大量的空闲线程,当向线程池提交任务时(需要线程来完成这个任务),
       线程池就会启动池内的一个线程来执行该任务,等待任务执行完成之后,线程并非直接死亡,而是再次返回线程池中,再次变为
       空闲状态,等待下一次任务的执行(再一次申请线程执行任务) */

        // 总结而言,线程池的意义主要是在于减少了线程的重复创建,通过线程池,线程可以重复利用,提高了效率

        // 设计思路:
        // 1.准备一个任务容器;
        // 2.一次性启动多个(至少2个)消费者线程
        // 3.刚开始任务容器是空的,所以说所有线程都是wait状态
        // 4.直到外部线程向任务容器中添加一个"任务",就有一个消费者线程被唤醒来执行这个任务
        // 5.消费者线程在任务容器中"取出"这个任务,然后执行这个任务,执行完毕后,继续等待下个任务

        // Executors默认线程池
        // JDK对线程池有默认实现------------Executors默认线程池,其实真实开发中也很少自定义线程池,大部分情况都是使用JDK默认线程池

        // 创建线程池
        // Executors静态方法创建
        // static ExecutorsService newCachedThreadPool()  创建一个默认的线程池
        // static newFixedThreadPool(int nThread)  创建一个指定最多线程数量的线程池

        // 创建一个默认的线程池对象,默认是空的,默认最多可以容纳int类型的最大值的线程(理论有限、实际无限)
        ExecutorService executorService = Executors.newCachedThreadPool();
        // Executors ------------ 可以帮助创建默认线程池对象
        // ExecutorService ------------ 可以帮助控制线程池
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "正在执行");
            }
        });

        //Thread.sleep(2000);

        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "正在执行");
            }
        });

        // 调用shutdown方法关闭线程池
        executorService.shutdown();
        /* 注:假如在两个任务提交的间隔加入sleep方法,线程池中只会有一条线程被使用,因为在sleep的时候,执行任务1的线程1已经执行
        完毕并返回线程池处于空闲状态,当任务2提交后,线程1处于空闲状态,所以说还是由线程1执行的任务2 */

    }
}

ThreadPoolExercise2

java 复制代码
package ThreadPoolExercise20240813;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class ThreadPoolExercise2 {
    public static void main(String[] args) {
        // static ExecutorService newFixedThreadPool(int nThread)  创建一个指定最多线程数的线程池

        // 参数不是初始值而是最大值
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 如此处参数传递10,并非是线程的初始数目就是10,而是线程池中的最大线程数是10

        ThreadPoolExecutor pool = (ThreadPoolExecutor) executorService;
        System.out.println(pool.getPoolSize()); //0
        // 可见最开始创建线程池,线程池中的线程是0

        executorService.submit(()->{
            System.out.println(Thread.currentThread().getName() + "在执行了");
        });

        executorService.submit(()->{
            System.out.println(Thread.currentThread().getName() + "在执行了");
        });

        System.out.println(pool.getPoolSize()); //2
        executorService.shutdown();

    }
}

ThreadExercise3

java 复制代码
package ThreadPoolExercise20240813;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

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

        // 创建线程池对象
        // ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1.核心线程的数量     int corePoolSize
        //                                                                2.最大线程的数量     int maximumPoolSize
        //                                                                3.空闲线程的最大存活时间     long keepAliveTime
        //                                                                4.时间单位     TimeUnit unit
        //                                                                5.任务队列     BlockingQueue<Runnable> workQueue
        //                                                                6.创建线程工厂     ThreadFactory threadFactory
        //                                                                7.任务的拒绝策略)     RejectedExecutionHandler handler

        // 各个参数的要求:
        // 1.核心线程数量:不能小于0
        // 2.最大线程数量:不能≤0,最大数量≥核心线程数量
        // 3.空闲线程的最大存活时间:不能小于0
        // 4.时间单位:正确的时间单位
        // 5.任务队列:不能为null
        // 6.创建线程工厂:不能为null
        // 7.任务的拒绝策略:不能为null

        // 非默认的任务拒绝策略
        // RejectedExecutionHandler 是JDK提供的一个任务拒绝策略的接口,存在以下子类:
        /*
         ThreadPoolExecutor.AbortPolicy: 		    丢弃任务并抛出RejectedExecutionException异常。是默认的策略。
         ThreadPoolExecutor.DiscardPolicy: 		   丢弃任务,但是不抛出异常 这是不推荐的做法。
         ThreadPoolExecutor.DiscardOldestPolicy:    抛弃队列中等待最久的任务 然后把当前任务加入队列中。
         ThreadPoolExecutor.CallerRunsPolicy:        调用任务的run()方法绕过线程池直接执行。
        */

        /*
         核心线程数量为1 , 最大线程池数量为3, 任务容器的容量为1 ,空闲线程的最大存在时间为20s
        */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1 , 3 , 20 , TimeUnit.SECONDS ,
                new ArrayBlockingQueue<>(1) , Executors.defaultThreadFactory() , new ThreadPoolExecutor.AbortPolicy()) ;

        // 线程池最大可执行任务数 = 队列容量 + 最大线程数

        // 提交5个任务,而该线程池最多可以处理4个任务,当我们使用AbortPolicy这个任务处理策略的时候,就会抛出异常
        for(int x = 0 ; x < 5 ; x++) {
            threadPoolExecutor.submit(() -> {
                System.out.println(Thread.currentThread().getName() + "---->> 执行了任务");
            });
        }
        // 一共有4个线程执行了任务,到了第五个任务时,抛出异常
    }
}
相关推荐
迷迭所归处2 分钟前
C++ —— 关于vector
开发语言·c++·算法
架构文摘JGWZ31 分钟前
Java 23 的12 个新特性!!
java·开发语言·学习
leon62532 分钟前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab
拾光师1 小时前
spring获取当前request
java·后端·spring
aPurpleBerry1 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j
锦亦之22331 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
我是苏苏1 小时前
Web开发:ABP框架2——入门级别的增删改查Demo
java·开发语言
姜太公钓鲸2332 小时前
c++ static(详解)
开发语言·c++
菜菜想进步2 小时前
内存管理(C++版)
c语言·开发语言·c++
xujinwei_gingko2 小时前
Spring IOC容器Bean对象管理-Java Config方式
java·spring