先上原理图:为了更好的在手机上显示,我重新把图画了一遍

上代码之前,要先补充一下线程池构造的核心几个点

  1. 线程池里的核心线程数与最大线程数

  2. 线程池里真正工作的线程worker

  3. 线程池里用来存取任务的队列BlockingQueue

  4. 线程中的任务task

本例实现简化了一些,只实现了BlockingQueue存放任务,然后每个worker取任务并执行,下面看代码
首先定义一个线程池ThreadExcutor

class ThreadExcutor{    //创建private volatile boolean RUNNING = true;    //所有任务都放队列中,让工作线程来消费private static BlockingQueue<Runnable> queue = null;    private final HashSet<Worker> workers = new HashSet<Worker>();    private final List<Thread> threadList = new ArrayList<Thread>();    //工作线程数int poolSize = 0;    //核心线程数(创建了多少个工作线程)int coreSize = 0;    boolean shutdown = false;    public ThreadExcutor(int poolSize){        this.poolSize = poolSize;queue = new LinkedBlockingQueue<Runnable>(poolSize);}    public void exec(Runnable runnable) {        if (runnable == null) throw new NullPointerException();        if(coreSize < poolSize){addThread(runnable);}else{            //System.out.println("offer" +  runnable.toString() + "   " + queue.size());try {queue.put(runnable);} catch (InterruptedException e) {e.printStackTrace();}}}    public void addThread(Runnable runnable){coreSize ++;Worker worker = new Worker(runnable);workers.add(worker);Thread t = new Thread(worker);threadList.add(t);        try {t.start();}catch (Exception e){e.printStackTrace();}}    public void shutdown() {RUNNING = false;        if(!workers.isEmpty()){            for (Worker worker : workers){worker.interruptIfIdle();}}shutdown = true;Thread.currentThread().interrupt();}   //这里留个位置放内部类Worker}

然后定义一个内部类Worker,这个内部类Worker是用来执行每个任务的,在创建线程池后,往线程里添加任务,每个任务都是由Worker一个一个来启动的。

    /*** 工作线程*/class  Worker implements Runnable{        public Worker(Runnable runnable){queue.offer(runnable);}        @Overridepublic void run() {            while (true && RUNNING){                if(shutdown == true){Thread.interrupted();}Runnable task = null;                try {task = getTask();task.run();} catch (InterruptedException e) {e.printStackTrace();}}}        public Runnable getTask() throws InterruptedException {            return queue.take();}        public void interruptIfIdle() {            for (Thread thread :threadList) {System.out.println(thread.getName() + " interrupt");thread.interrupt();}}}

首先注意的一点,这个Worker是个内部类,是在线程池内声明的。

exec方法
Worker怎么工作

这个工作线程实例化的时候就先加入一个任务到队列中,也就是说在实例化这个工作线程时,这个工作线程也是一个任务被加入到线程池中。然后就是run方法,这个run方法是线程调start方法生成的线程,而Worker调的run方法并没有生成新的线程。就是一个循环,一直在不停的从队列中取任务,然后执行。可以看到,取队列的方法是take(),这个方法意思如果队列为空了,取不到数据时就阻塞队列。

然后看shutdown()

你每天辛勤的劳动着,突然接收到上面的命令,说活暂时不要接了,先停下来,当你还没搞清楚状况时,接着你的领导又把你开除了,说公司要倒了,你先下岗吧,一会我也得下岗了。这就是shutdown做的事,shutdown必须是主线程才能停止工作线程。
shutdown方法并不是用线程那种强制停止的搞法,而是先用一个标识符告诉工作线程,不要再接任务了。然后通知工作线程,你可以interrupt()了,当所有的线程停止后记得要把主线程也停掉,这样,一个简单任务的线程池就完成了。
让我们来测试一下:

/*** Created by wxwall on 2017/6/7.*/public class TheadBlockedQ {    public static void main(String[] args) throws InterruptedException {ThreadExcutor excutor = new ThreadExcutor(3);        for (int i = 0; i < 10; i++) {excutor.exec(new Runnable() {@Override                public void run() {System.out.println("线程 " + Thread.currentThread().getName() + " 在帮我干活");}});}excutor.shutdown();}
}

输出结果为:

线程 Thread-0 在帮我干活
线程 Thread-2 在帮我干活
线程 Thread-1 在帮我干活
线程 Thread-0 在帮我干活
线程 Thread-2 在帮我干活
线程 Thread-2 在帮我干活
线程 Thread-1 在帮我干活
线程 Thread-0 在帮我干活
Thread-0 interrupt
Thread-1 interrupt
Thread-2 interrupt
Thread-0 interrupt
Thread-1 interrupt
Thread-2 interrupt
Thread-0 interrupt
Thread-1 interrupt
Thread-2 interrupt

这当然是最简单实现,JDK的实现比这强大的多,而且还具备当工作线程处理不过来时,可以产生新的线程来处理任务,这个数量不能超过原先定义的最大线程数,而在本例中都没实现这些功能。
我相信当想了解一个模块的功能时,如果一开始就了解其中最核心的点,然后向外慢慢扩展,那么学习这个模块时一定能省下不少时间,而且理解将很深刻。希望这个简单线程池实现能让你有所领悟,以更加简单的方式了解线程池,了解了线程池,对于其他池化技术,原理都是相通的。

本文转自  zddnd  51CTO博客,原文链接:http://blog.51cto.com/13013666/1940090

java基础:简单实现线程池相关推荐

  1. Java基础知识:线程池的种类(5种)

    JDK的线程池,它是预先创建好一些线程,放在池中.用的时候从池中取线程,用完放回池中. 避免了创建,销毁线程的开销.与数据库连接池是同样的道理. 1.固定数量的线程池 newFixedThreadPo ...

  2. 腾讯面试题Java 并发包之线程池综述

    Java 并发包之线程池综述 ■ 线程池的创建 在Java中,您可以通过调整-Xss参数来调节每个线程栈的大小(64bit系统默认1024KB),当减小该值时意味着可以创建更多的线程数,但问题是JVM ...

  3. Java基础教程-10-多线程

    Java基础教程-10-多线程 1. 多线程 我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏边听歌,怎么设计? 要解决上述问题,咱们得使用多进程或 ...

  4. 多线程-使用大全 基础使用 / 锁 / 线程池 / 原子类 / 并发包 / CAS / AQS (2022版)

    一.多线程描述 1.什么是cpu CPU的中文名称是中央处理器,是进行逻辑运算用的主要由运算器.控制器.寄存器三部分组成, 运算器:从字面意思看就是运算就是起着运算的作用, 控制器:就是负责发出cpu ...

  5. 手写一个简单的线程池MyThreadPool

    说明 手写的一个简单的线程池,旨在帮助了解线程池的工作原理. 核心内容 核心工作线程 任务阻塞队列 定义一个内部类去实现核心工作线程 /*** 内部类:工作的核心线程*/private final c ...

  6. [转]Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  7. Java多线程系列 JUC线程池01 线程池框架

    转载  http://www.cnblogs.com/skywang12345/p/3509903.html 为什么引入Executor线程池框架 new Thread()的缺点 1. 每次new T ...

  8. Java并发编程一线程池简介

    推荐:Java并发编程汇总 Java并发编程一线程池简介 为什么我们需要使用线程池? 我们知道线程是一种比较昂贵的资源,我们通过程序每创建一个线程去执行,其实操作系统都会对应地创建一个线程去执行我们的 ...

  9. Java异步并发和线程池

    Java异步并发和线程池 1.一条简单粗暴的路: a.使用 parallelStream可能存在的bug b. 如何正确使用 parallelStream 2.另一条路 参考1: https://we ...

  10. java构造单例线程池_java中常见的六种线程池详解

    之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊Java 中常见的几种线程池,以及在jdk7 加入的 ForkJoin 新型线程池 首先我们列出Java 中的六种线程池如 ...

最新文章

  1. smack连接openfire
  2. NetCore 2.0 MVC入门之 Startup 配置
  3. 2023年中国AI论文影响力超越美国?网友:长期看,数量不等于质量
  4. 三十、Java 多线程编程(上篇)
  5. c++ socket线程池_java 网络编程,Socket编程
  6. Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种...
  7. fopen的路径怎么写_用C++写光线追踪:单根光线的渲染
  8. 查看tensorflow是否支持GPU,以及测试程序
  9. mysql外键 菜鸟教程_MySQL 菜鸟入门“秘籍”
  10. ISO14001环境管理体系问答篇
  11. retinaface代码讲解_Pytorch-RetinaFace 详解
  12. 安卓开发者模式中将最小dp调得太高导致无法开机的解决方法
  13. CSS 基础教程:CSS 教程:什么是 CSS?
  14. 开心网android客户端,开心网Android客户端V3.8.1升级评测
  15. Windows10蓝屏提示错误操作Wdwifi.sys
  16. Offset is outside the bounds of the DataView
  17. SQL SERVER 插入时表名显示对象名无效 问题
  18. 【MapReduce】综合案例
  19. 2020-8-15词汇
  20. JavaScript原型是什么

热门文章

  1. Nginx入门简介和反向代理、负载均衡、动静分离理解
  2. Jquery中实现表单提交到SSM后台前进行post请求实现数据的校验
  3. Eclipse导入项目后中文乱码
  4. 讲故事的用户故事样例之1
  5. 使用 FocusScopeNode 在 TextFormFields 之间轻松移动焦点
  6. 冲刺 (sprint) 评审会议
  7. Java里optionsMenu.add_NoActionBar主题下如何添加OptionsMenu
  8. 电脑ping不通 plsql能连上_台式电脑不能上网手机却能连上wifi无线网络的解决方法...
  9. 周报速递丨北交所 SaaS 首股将出;央行等印发《金融标准化“十四五”发展规划》
  10. 神策数据荣获“2017金融科技·大数据优秀案例之最佳实践案例奖”