我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java简单实现线程池

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java简单实现线程池

本文实例为大家分享了Java简单实现线程池的具体代码,供大家参考,具体内容如下

一、线程池

线程池是一种缓冲提高效率的技术。
相当于一个池子,里面存放大量已经创建好的线程,当有一个任务需要处理时, 可以直接从池子里面取一个线程去执行它。 包括内存池,很多缓冲的技术都是采用这种技术。 其实理解起来很简答!

为什么需要线程池,这种池的技术?

1.1 减少开辟资源和销毁资源带来的损耗。

开辟线程,申请内存(具体的可以看C语言中malloc底层实现原理),销毁线程、释放内存资源等一些操作都是有时间消耗的。
因此一开始开辟大量的资源进行管理,需要使用时从池中取一个去使用, 使用完毕后再放回池中管理, 这样可以避免资源开辟和销毁带来的时间损耗。

1.2 提高响应。

用户来了一个请求, 能够立刻从开辟好的线程池中取一个线程去处理执行。 提高响应效率,提高用户体验。

1.3 有效管理资源

管理资源统一开辟和销毁, 监控线程状态和调优

二、线程池分析

对于线程池的实现我们划分为2个部分

1、线程安全的任务队列(采用队列,不过是线程安全的而已),保证工作线程在去任务时不会发生冲突(重复取同一个任务处理,二次执行或者多次的问题)。
2、对工作线程的监管(采用是List管理工作线程),方便线程的销毁和管理。

线程池处理逻辑:

1、每当添加一个任务,就会从线程池中取一个工作线程去处理执行它。
2、没有任务处理时, 工作线程应该处于阻塞状态等待任务到来, 不会竞争占用CPU资源
3、线程池相当于生产-消费模型, 只不过生产线程的中生产任务不同罢了。

3、主线程相当于监管线程,最终负责工作线程的销毁。

三、线程池实现

1、 工作线程Worker

1.1、工作线程负责从阻塞任务队列中取出任务执行。由于存在很多个线程对同一个队列操作,因此这个任务队列一定得是线程安全的(采用BlockingQueue接口, 这是GUC提供的,线程安全)
1.2、工作线程的创建方式属于线程创建的方式之一。
1.3、每个工作线程都维护一个阻塞任务队列。
1.4、线程的执行方法run()中,以线程的中断状态为循环判断条件(方便线程销毁, 只要将工作线程的中断状态置为true即可释放工作线程)其次就是BlockingQueue接口提供的take()方法。

该方法在队列没有元素时处于阻塞状态,直接取到元素,这样就解决了没有任务工作线程处于阻塞状态,不会抢占CPU


//实现工作线程 - 工作线程中维护了公有的任务队列(阻塞), 工作线程的执行逻辑。 循环取队列中的任务去执行处理。
class Worker extends Thread {
    //阻塞任务队列 - 可以保证多个线程对队列操作, 线程安全
    private BlockingQueue<Runnable> queue = null;
    //每个工作线程都会有一个阻塞队列,这个队列中保存了所有的任务
    public Worker(BlockingQueue<Runnable> queue, int id) {
        this.queue = queue;
     //   Thread.currentThread().setName("郝梦武" + id + "号工作线程");
    }
    
    //工作线程执行内容
    @Override
    public void run() {
        //每个线程通过isInterrupted()判断线程异常状态。
        try {
            while (!Thread.currentThread().isInterrupted()) {
                //如果线程正常, 返回false, 出现异常, 返回true, 该状态默认为false
                Runnable command = queue.take();    //如果队列为空, take会让线程阻塞
                System.out.println(Thread.currentThread().getName() + "正在处理任务" + command.hashCode());
                command.run();
            }
        }
        catch(InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + "被中止了");
        //    e.printStackTrace();      //不需要抛出异常
        }
    }
}

2、线程池对象MyThreadPool

1、创建工作线程并管理,添加任务。
2、销毁所有工作线程


//线程池 - 维护很多个线程, 当来一个任务时, 从线程池中获取一个线程去处理执行。
//好处: 防止线程频繁开辟和销毁带来的性能损耗
class MyThreadPool {
    //创建任务线程安全的队列, 保证多个线程对这个队列操作时是线程安全的
    private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
    //线程管理列表 - 这个列表保存了所有线程对象的引用, 方便后续的管理
    private List<Worker> Wokers = new ArrayList<>();
    private final static int maxWorkerCount = 10;   //线程池最大允许的个数

    //execute方法
    public void execute(Runnable command) throws InterruptedException {
        if(Wokers.size() < maxWorkerCount) {
            //创建一个新的工作线程
            Worker worker = new Worker(queue, Wokers.size());   //创建工作线程
            worker.start();                      //创建的工程线程启动
            Wokers.add(worker);                  //添加到管理列表中
        }
        queue.put(command);                      //添加任务到线程安全的队列中
    }

    //销毁所有线程 - 将每个线程中状态置为中断状态方法, 并且
    public void shutDown() throws InterruptedException {
        for(Worker worker : Wokers) {
            worker.interrupt();                  //将线程的状态置为中断, 调用isInterruptd()返回值为true
        }
        //并且让主线程join阻塞等待所有工作线程
        for(Worker worker : Wokers) {
            worker.join();                       //join方法可以让调用的线程处于阻塞状态, 知道等待的线程结束完毕之后就会恢复
        }
        //执行到这块, 代表所有的线程销毁完毕
        System.out.println("所有工作线程销毁完毕!");
    }
}

3、测试代码


class MyRunnable implements Runnable {
    private int num;
    MyRunnable(int num) {
        this.num = num;
    }
    @Override
    public void run() {
        System.out.println("正在执行任务: " + num);
    }
}

public static void main(String[] args) throws InterruptedException {
     MyThreadPool myThreadPool = new MyThreadPool();
     for(int i = 0; i < 1000; i++) {
         myThreadPool.execute(new MyRunnable(i + 1));
     }
     Thread.sleep(2000);   //主线程休眠2s
     myThreadPool.shutDown();  //销毁所有工作线程
     System.out.println("线程池已经被销毁了");
     }

4、测试结果

总结:

以上的代码只是简单模拟实现了线程池。
不仅仅是线程池,内容池,还有很多池的应用场景。
池的技术虽然能够起到快速响应的特点,但是还是存在问题。
第一点: 池需要在一开始创建很多资源, 这和我们机器内存大小有关系。
第二点: 池中的线程过多,但是任务过少,导致很多线程浪费掉, 因此池中开辟多大的资源需要根据实际情况而言。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java简单实现线程池

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何实现java简单的线程池

这篇文章主要讲解了“如何实现java简单的线程池”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现java简单的线程池”吧!目录拆分实现流程实现方式1.拒绝策略2.阻塞队列3.线程池和工
2023-06-20

Linux C线程池简单实现实例

Linux C线程池 三个文件 1 tpool.htypedef struct tpool_work { void (*routine)(void *); void *arg; struct tpool_work
2022-06-04

用Python实现一个简单的线程池

线程池的概念是什么?在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是 如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能
2023-01-31

C++怎么实现一个简单的线程池

本文小编为大家详细介绍“C++怎么实现一个简单的线程池”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++怎么实现一个简单的线程池”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、设计线程池应该包括保存线程的容
2023-06-30

python进程池的简单实现

本文主要介绍了python进程池的简单实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-03-13

python 多线程简单实现

1. 线程是什么?线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。2 为什么要用线程?a 单个线程可以在进程中独立运行c 并行操作,适用于C/S架构3 python怎么生成线程(将函数生
2023-01-31

Java线程池的实现方法

本篇内容主要讲解“Java线程池的实现方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java线程池的实现方法”吧!以前做的东西,实现一个简单的多线程机制,开始之前,现说说原理性的东西吧,下面
2023-06-17

怎么用JAVA实现简单Thread缓冲池

本篇内容主要讲解“怎么用JAVA实现简单Thread缓冲池”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用JAVA实现简单Thread缓冲池”吧!在应用中,我们常常需要Thread缓冲池来做
2023-06-03

python 进程池pool简单实例

进程池:      在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十
2023-01-31

简单谈谈ThreadPoolExecutor线程池之submit方法

jdk1.7.0_79 在上一篇《ThreadPoolExecutor线程池原理及其execute方法》中提到了线程池ThreadPoolExecutor的原理以及它的execute方法。本文解析ThreadPoolExecutor#sub
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录