0

0

Java如何使用线程池?代码实现。

WBOY

WBOY

发布时间:2023-05-08 14:31:07

|

2215人浏览过

|

来源于亿速云

转载

Java线程池核心原理

看过java线程池源码的小伙伴都知道,在java线程池中最核心的类就是threadpoolexecutor,而在threadpoolexecutor类中最核心的构造方法就是带有7个参数的构造方法,如下所示。

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

各参数的含义如下所示。

  • corePoolSize:线程池中的常驻核心线程数。

  • maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值大于等于1。

  • keepAliveTime:多余的空闲线程存活时间,当空间时间达到keepAliveTime值时,多余的线程会被销毁直到只剩下corePoolSize个线程为止。

    立即学习Java免费学习笔记(深入)”;

  • unit:keepAliveTime的单位。

  • workQueue:任务队列,被提交但尚未被执行的任务。

  • threadFactory:表示生成线程池中工作线程的线程工厂,用户创建新线程,一般用默认即可。

  • handler:拒绝策略,表示当线程队列满了并且工作线程大于等于线程池的最大显示数(maxnumPoolSize)时,如何来拒绝请求执行的runnable的策略。

并且Java的线程池是通过 生产者-消费者模式 实现的,线程池的使用方是生产者,而线程池本身就是消费者。

Java线程池的核心工作流程如下图所示。

Java线程池代码怎么写

手撸Java线程池

我们自己手动实现的线程池要比Java自身的线程池简单的多,我们去掉了各种复杂的处理方式,只保留了最核心的原理:线程池的使用者向任务队列中添加任务,而线程池本身从任务队列中消费任务并执行任务。

Java线程池代码怎么写

只要理解了这个核心原理,接下来的代码就简单多了。在实现这个简单的线程池时,我们可以将整个实现过程进行拆解。拆解后的实现流程为:定义核心字段、创建内部类WorkThread、创建ThreadPool类的构造方法和创建执行任务的方法。

定义核心字段

首先,我们创建一个名称为ThreadPool的Java类,并在这个类中定义如下核心字段。

  • DEFAULT_WORKQUEUE_SIZE:静态常量,表示默认的阻塞队列大小。

    动感购物HTML
    动感购物HTML

    修正了V1.10的一些BUG感购物HTML系统是集合目前网络所有购物系统为参考而开发,代码采用DIV编号,不管从速度还是安全我们都努力做到最好,此版虽为免费版但是功能齐全,无任何错误,特点有:专业的、全面的电子商务解决方案,使您可以轻松实现网上销售;自助式开放性的数据平台,为您提供充满个性化的设计空间;功能全面、操作简单的远程管理系统,让您在家中也可实现正常销售管理;严谨实用的全新商品数据库,便于

    下载
  • workQueue:模拟实际的线程池使用阻塞队列来实现生产者-消费者模式。

  • workThreads:模拟实际的线程池使用List集合保存线程池内部的工作线程。

核心代码如下所示。

//默认阻塞队列大小
private static final int DEFAULT_WORKQUEUE_SIZE = 5;

//模拟实际的线程池使用阻塞队列来实现生产者-消费者模式
private BlockingQueue workQueue;

//模拟实际的线程池使用List集合保存线程池内部的工作线程
private List workThreads = new ArrayList();

创建内部类WordThread

在ThreadPool类中创建一个内部类WorkThread,模拟线程池中的工作线程。主要的作用就是消费workQueue中的任务,并执行任务。由于工作线程需要不断从workQueue中获取任务,所以,这里使用了while(true)循环不断尝试消费队列中的任务。

核心代码如下所示。

//内部类WorkThread,模拟线程池中的工作线程
//主要的作用就是消费workQueue中的任务,并执行
//由于工作线程需要不断从workQueue中获取任务,使用了while(true)循环不断尝试消费队列中的任务
class WorkThread extends Thread{
    @Override
    public void run() {
        //不断循环获取队列中的任务
        while (true){
            //当没有任务时,会阻塞
            try {
                Runnable workTask = workQueue.take();
                workTask.run();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

创建ThreadPool类的构造方法

这里,我们为ThreadPool类创建两个构造方法,一个构造方法中传入线程池的容量大小和阻塞队列,另一个构造方法中只传入线程池的容量大小。

核心代码如下所示。

//在ThreadPool的构造方法中传入线程池的大小和阻塞队列
public ThreadPool(int poolSize, BlockingQueue workQueue){
    this.workQueue = workQueue;
    //创建poolSize个工作线程并将其加入到workThreads集合中
    IntStream.range(0, poolSize).forEach((i) -> {
        WorkThread workThread = new WorkThread();
        workThread.start();
        workThreads.add(workThread);
    });
}

//在ThreadPool的构造方法中传入线程池的大小
public ThreadPool(int poolSize){
    this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
}

创建执行任务的方法

在ThreadPool类中创建执行任务的方法execute(),execute()方法的实现比较简单,就是将方法接收到的Runnable任务加入到workQueue队列中。

核心代码如下所示。

//通过线程池执行任务
public void execute(Runnable task){
    try {
        workQueue.put(task);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

完整源码

这里,我们给出手动实现的ThreadPool线程池的完整源代码,如下所示。

package io.binghe.thread.pool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 自定义线程池
 */
public class ThreadPool {

    //默认阻塞队列大小
    private static final int DEFAULT_WORKQUEUE_SIZE = 5;

    //模拟实际的线程池使用阻塞队列来实现生产者-消费者模式
    private BlockingQueue workQueue;

    //模拟实际的线程池使用List集合保存线程池内部的工作线程
    private List workThreads = new ArrayList();

    //在ThreadPool的构造方法中传入线程池的大小和阻塞队列
    public ThreadPool(int poolSize, BlockingQueue workQueue){
        this.workQueue = workQueue;
        //创建poolSize个工作线程并将其加入到workThreads集合中
        IntStream.range(0, poolSize).forEach((i) -> {
            WorkThread workThread = new WorkThread();
            workThread.start();
            workThreads.add(workThread);
        });
    }

    //在ThreadPool的构造方法中传入线程池的大小
    public ThreadPool(int poolSize){
        this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
    }

 //通过线程池执行任务
    public void execute(Runnable task){
        try {
            workQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //内部类WorkThread,模拟线程池中的工作线程
    //主要的作用就是消费workQueue中的任务,并执行
    //由于工作线程需要不断从workQueue中获取任务,使用了while(true)循环不断尝试消费队列中的任务
    class WorkThread extends Thread{
        @Override
        public void run() {
            //不断循环获取队列中的任务
            while (true){
                //当没有任务时,会阻塞
                try {
                    Runnable workTask = workQueue.take();
                    workTask.run();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

没错,我们仅仅用了几十行Java代码就实现了一个极简版的Java线程池,没错,这个极简版的Java线程池的代码却体现了Java线程池的核心原理。

接下来,我们测试下这个极简版的Java线程池。

编写测试程序

测试程序也比较简单,就是通过在main()方法中调用ThreadPool类的构造方法,传入线程池的大小,创建一个ThreadPool类的实例,然后循环10次调用ThreadPool类的execute()方法,向线程池中提交的任务为:打印当前线程的名称--->> Hello ThreadPool

整体测试代码如下所示。

package io.binghe.thread.pool.test;

import io.binghe.thread.pool.ThreadPool;

import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 测试自定义线程池
 */
public class ThreadPoolTest {

    public static void main(String[] args){
        ThreadPool threadPool = new ThreadPool(10);
        IntStream.range(0, 10).forEach((i) -> {
            threadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "--->> Hello ThreadPool");
            });
        });
    }
}

接下来,运行ThreadPoolTest类的main()方法,会输出如下信息。

Thread-0--->> Hello ThreadPoolThread-9--->> Hello ThreadPoolThread-5--->> Hello ThreadPoolThread-8--->> Hello ThreadPoolThread-4--->> Hello ThreadPoolThread-1--->> Hello ThreadPoolThread-2--->> Hello ThreadPoolThread-5--->> Hello ThreadPoolThread-9--->> Hello ThreadPoolThread-0--->> Hello ThreadPool

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

834

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

738

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

734

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

9

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.6万人学习

C# 教程
C# 教程

共94课时 | 6.8万人学习

Java 教程
Java 教程

共578课时 | 46.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号