手写JAVA线程池

这篇具有很好参考价值的文章主要介绍了手写JAVA线程池。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

手写一个简单的java线程池:重点关注,如何确保一直有运行的线程?如何确保线程消费提交的任务信息?。一直保存有运行的线程底层使用的是死循环。使用消息队列确保信息的提交和消费。消息队列使用先进先出原则。

步骤

线程池核心点 :复用机制

  • 1、提前创建好固定的线程一直在运行状态----死循环实现
  • 2、提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行
  • 3、正在运行的线程就从队列中获取该任务执行

1、创建固定线程

根据传入的参数,确定要生成几个一直运行的线程。比如传入的参数是2,就会创建出2个一直运行的线程。一直运行的线程使用死循环来实现。

public class MyTestExecutors {
    private List<WorkThread> workThread;

    /**
     * 最大线程数
     * @param maxThreadCount
     */
    public MyTestExecutors(int maxThreadCount){
        //提前创建好固定的线程一直在运行状态---死循环实现
        workThread = new ArrayList<WorkThread>(maxThreadCount);
        for (int i = 0; i < maxThreadCount; i++) {
            new WorkThread().start();
        }
    }

    class WorkThread extends Thread{
        @Override
        public void run() {
            while (true){

            }
        }
    }
}

2、提交任务到消息队列

提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行。

提示:offer()方法是Java队列中经常使用的方法,它的作用是向队列尾部添加一个元素。具体来说,offer()方法会将指定的元素插入到此队列的末尾,如果队列已满,它将返回false。否则,它会返回true,表示已成功添加了元素。

    /**
     * 线程任务缓存到一个并发队列集合
     * @param command
     * @return
     */
    public boolean execute(Runnable command){
        return runnableDeque.offer(command);
    }

public class MyTestExecutors {
    private List<WorkThread> workThread; //工作线程
    private BlockingDeque<Runnable> runnableDeque; //队列


    /**
     * @param maxThreadCount 最大线程数
     * @param dequeSize      缓存消息队列
     */
    public MyTestExecutors(int maxThreadCount,int dequeSize){
        //1、限制队列容量缓存
        runnableDeque = new LinkedBlockingDeque<Runnable>(dequeSize);
        //2、提前创建好固定的线程一直在运行状态---死循环实现
        workThread = new ArrayList<WorkThread>(maxThreadCount);
        for (int i = 0; i < maxThreadCount; i++) {
            new WorkThread().start();
        }

    }

    class WorkThread extends Thread{
        @Override
        public void run() {
            while (true){

            }
        }
    }

    /**
     * 线程任务缓存到一个并发队列集合
     * @param command
     * @return
     */
    public boolean execute(Runnable command){
        return runnableDeque.offer(command);
    }

    public static void main(String[] args) {
        MyTestExecutors testExecutors = new MyTestExecutors(2, 2);
        for (int i = 0; i < 10; i++) {
            final int finalI = i;
            testExecutors.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+","+finalI);
                }
            });
        }
    }
}

3、线程消费消息队列

正在运行的线程就从队列中获取该任务执行

    class WorkThread extends Thread{
        @Override
        public void run() {
            while (true){
                Runnable runnable = runnableDeque.poll();
                if(runnable != null){
                    runnable.run();
                }
            }
        }
    }

4、测试

2个的情况,两个固定线程还未执行任务,且队列中只缓存了两个线程任务。

手写JAVA线程池,Java编程思想,java,开发语言

4个的情况,固定两个线程正在执行任务,队列中缓存了两个线程任务。
手写JAVA线程池,Java编程思想,java,开发语言

5、线程停止【完整代码】

如何在线程任务执行完成后,停止两个一直存在的线程。需要将死循环的条件改变,通过给一个标志位。在任务结束后,将该标志位设置为false,同时需要判断,队列中的任务是否执行结束。队列中缓存的任务全部结束,才停止线程。

while (isRun || runnableDeque.size()>0)

package com.grg.demo.testDemo02;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @author zyz
 * @version 1.0
 * @data 2023/7/11 23:01
 * @Description: 手写线程池
 *  线程池核心点 :复用机制 -----
 *  1、提前创建好固定的线程一直在运行状态----死循环实现
 *  2、提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行
 *  3、正在运行的线程就从队列中获取该任务执行
 */
public class MyTestExecutors {
    private List<WorkThread> workThread; //工作线程
    private BlockingDeque<Runnable> runnableDeque; //队列
    private Boolean isRun = true;

    /**
     *
     * @param maxThreadCount 最大线程数
     * @param dequeSize      缓存消息队列
     */
    public MyTestExecutors(int maxThreadCount,int dequeSize){
        //2、限制队列容量缓存
        runnableDeque = new LinkedBlockingDeque<Runnable>(dequeSize);
        //1、提前创建好固定的线程一直在运行状态---死循环实现
        workThread = new ArrayList<WorkThread>(maxThreadCount);
        for (int i = 0; i < maxThreadCount; i++) {
            new WorkThread().start();
        }

    }

    class WorkThread extends Thread{
        @Override
        public void run() {
            while (isRun || runnableDeque.size()>0){
                Runnable runnable = runnableDeque.poll();
                if(runnable != null){
                    runnable.run();
                }
            }
        }
    }

    /**
     * 线程任务缓存到一个并发队列集合
     * @param command
     * @return
     */
    public boolean execute(Runnable command){
        return runnableDeque.offer(command);
    }

    public static void main(String[] args) {
        MyTestExecutors testExecutors = new MyTestExecutors(2, 2);
        for (int i = 0; i < 10; i++) {
            final int finalI = i+1;
            testExecutors.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+","+finalI);
                }
            });
        }
        testExecutors.isRun = false;
    }
}

手写JAVA线程池,Java编程思想,java,开发语言文章来源地址https://www.toymoban.com/news/detail-557148.html

到了这里,关于手写JAVA线程池的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 编程开发8大语言详解,为什么Java是我最推荐的?

    很多没有接触过编程语言的同学,都会觉得编程开发特别高端和神奇,担心理解不了更担心学不会。 当然,也有人会认为,你既然是做编程的,那么你应该什么都会,什么软件的开发都能完成,这是平哥经常听到的两种声音。 在此,平哥需要给大家科普一下, 编程确实改变

    2024年02月05日
    浏览(73)
  • [ XJTUSE ]JAVA语言基础知识——第一章 面向对象程序设计思想

    类描述了一组有相同 特性 (属性)和相同 行为 (方法)的对象,类和对象是面向对象思想的两个核心概念 · 人类是一种类,每一个具体的人则是这个类的对象 用面向对象程序来模拟真实世界 发现并创建类 发现类的特征 发现类的行为 在面向对象程序中,对象的特征由各种

    2023年04月13日
    浏览(93)
  • 计算机网络技术与JAVA网络编程手写Socket聊天室-----JAVA入门基础教程-----计算机网络经典

    import java.io.*; import java.net.Socket; import java.util.Scanner; public class ChatClient { public static void main(String[] args) { try { Socket socket = new Socket(\\\"127.0.0.1\\\",9090); new Thread(new Runnable() { @Override public void run() { InputStream inputStream = null; while(true) { try { inputStream = socket.getInputStream(); } catch (IOException e)

    2024年02月15日
    浏览(61)
  • 【Java 基础篇】Java多线程编程详解:线程创建、同步、线程池与性能优化

    Java是一门强大的编程语言,其中最引人注目的特性之一是多线程支持。多线程允许我们在同一程序中同时执行多个任务,这大大提高了应用程序的性能和响应能力。本文将深入介绍Java线程的基础知识,无论您是初学者还是有一些经验的开发人员,都将从中获益。 在计算机科

    2024年02月07日
    浏览(57)
  • 玄子Share-自然语言编程(NLP)_Java开发小白向 ChatGPT 提问的最佳模板

    以下内容均为 ChatGPT 回答 玄子: 我向你提问时,问题描述精确的重要性 ChatGPT 3.5 问题描述的精确性非常重要,因为它可以让回答者更好地理解您的问题,并且更容易提供准确和有用的解决方案。如果问题描述不够清晰或不够详细,回答者可能会误解您的问题或者理解不到位

    2023年04月09日
    浏览(50)
  • 「Java」《深入解析Java多线程编程利器:CompletableFuture》

    多线程编程是指在一个程序中同时执行多个线程来提高系统的并发性和响应性。在现代计算机系统中,多线程编程已经成为开发者日常工作的一部分。以下是对多线程编程需求和挑战的介绍: 需求: 提高系统的性能:通过同时执行多个线程,可以利用多核处理器的优势,实

    2024年02月11日
    浏览(50)
  • 【Java 并发编程】Java 线程本地变量 ThreadLocal 详解

    先一起看一下 ThreadLocal 类的官方解释: 用大白话翻译过来,大体的意思是: ThreadLoal 提供给了 线程局部变量 。同一个 ThreadLocal 所包含的对象,在不同的 Thread 中有不同的副本。这里有几点需要注意: 因为每个 Thread 内有自己的实例副本,且 该副本只能由当前 Thread 使用 。

    2024年02月04日
    浏览(71)
  • Java 多线程编程

      目录 Java 多线程编程 一个线程的生命周 线程的优先级 创建一个线程 通过实现Runnable接口来创建线程 实例 通过继承Thread来创建线程 实例 Thread 方法 实例   线程的几个主要概念: 多线程的使用     Java给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发

    2024年02月08日
    浏览(32)
  • Java多线程编程中的线程同步

    基本概念: ​ 线程同步是多线程编程中的一个重要概念,用于控制多个线程对共享资源的访问,以防止数据的不一致性和并发问题。 在多线程环境下,多个线程同时访问共享资源可能导致数据的竞争和不正确的结果。 是确保多个线程按照特定的顺序和规则访问共享资源,以

    2024年02月13日
    浏览(47)
  • Java多线程编程中的线程死锁

    ​ 在多线程编程中,线程死锁是一种常见的问题,它发生在两个或多个线程互相等待对方释放资源的情况下,导致程序无法继续执行 。本文将介绍线程死锁的概念、产生原因、示例以及如何预防和解决线程死锁问题。 线程死锁的概念 ​ 线程死锁是指两个或多个线程被阻塞

    2024年02月12日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包