首页 > 编程语言 >Java多线程(3):ThreadPool(上)

Java多线程(3):ThreadPool(上)

时间:2022-10-24 06:44:07浏览次数:58  
标签:Java Worker 任务 ThreadPool Manager 线程 new 多线程 public

您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~

 

开完一趟车完整的过程是启动、行驶和停车,但老司机都知道,真正费油的不是行驶,而是长时间的怠速、频繁地踩刹车等动作。因为在速度切换的过程中,发送机要多做一些工作,当然就要多费一些油。

而一个Java线程完整的生命周期就包括:

1、T1:创建(启动)

2、T2:运行(行驶)

3、T3:销毁(停车)

而T1 + T3的开销(汽油或者时间)是要远大于T2的。所以,即使是性能再好的车,或者性能再好的计算机,如果经常有T1 + T3的操作存在,那么显然是扛不住的。

所以,为了解决这种因为切换不同线程导致的效率问题,Java推出了线程池技术。通过对已创建线程的合理重用,既能解决上述问题,又能进一步提高响应速度,提升系统性能和稳定性。线程池特别适合下面的应用场景:

1、单个任务处理时间较短

2、需要处理的任务数量大

比如硬件数据采集,像手机、车载和安防传感器的数据采集就特别符合这种情况。

这是线程池相关继承结构图:

 

 

 

 

很多人都分不清Executor和Executors这两个东西:Executor是接口,是一个根据一组执行策略调用、调度、执行和控制的异步任务框架,提供了一种将“任务提交”与“任务如何运行”分离开的机制。而Executors则是一个工具类(不用new),提供了诸多用于线程池的静态方法。Executor和Executors的关系,和Java I/O中Collection和Collections的关系一毛一样。所以下次再看到XXX和XXXs的时候应该就知道Java的调性了。

说起来还是有点枯燥,那么我拿之前做的一个例子来说一下就明白了。

假设有一个工地有若干项目经理和工人,1个经理+1个工人组成工作小队,工地有很多个这样的工作小队,这些工作小队需要加入项目组,但是只有有活干的才能加入,没活干的加不了,就能要被优化裁员。

/**
 * 工人
 *
 * @author 湘王
 */
public class Worker {
    /**
     * 干活
     */
    public void dosomething() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("挖坑");
    }
}

 

/**
 * 经理
 *
 * @author 湘王
 */
public class Manager implements Runnable {
    private Worker worker;

    public Worker getWorker() {
        return worker;
    }

    public void setWorker(Worker worker) {
        this.worker = worker;
    }

    /**
     * 经理动嘴,工人动手
     */
    @Override
    public void run() {
        worker.dosomething();
    }
}

 

 

/**
 * 项目组
 *
 * @author 湘王
 */
public class ManagerGroup {
    private static ExecutorService projectGroup = new ThreadPoolExecutor(
            3, // 核心小队数量
            3, // 最多能容纳多少个小队
            30, // 多久没活干就请出项目组
            TimeUnit.SECONDS, // 时间单位
            new ArrayBlockingQueue<Runnable>(3),// 有多少个项目经理就不再接收入组申请
            new ThreadPoolExecutor.CallerRunsPolicy() // 项目组拒绝响应时怎么处理
    );

    // 项目组增加工作小队
    public static void addTask(Manager manager) {
        projectGroup.execute(manager);
    }

    public static void main(String[] args) {
        Manager manager1 = new Manager();
        Worker worker1 = new Worker();
        manager1.setWorker(worker1);

        Manager manager2 = new Manager();
        Worker worker2 = new Worker();
        manager2.setWorker(worker2);

        Manager manager3 = new Manager();
        Worker worker3 = new Worker();
        manager3.setWorker(worker3);

        // 申请进入项目组有活干才可能不被优化
        ManagerGroup.addTask(manager1);
        ManagerGroup.addTask(manager2);
        ManagerGroup.addTask(manager3);
    }
}

 

 

可以自己将核心小组数量、最多能容纳的小队数量等数字调节一下,然后运行看看效果。

 

和线程一样,线程池也有自己的状态,而且和线程的状态差不多(想想也是,毕竟要符合线程生命周期的东西,确实应该差不多)。线程池状态:

 

 

 

1、RUNNING:正常运行,能接收新任务,也能处理阻塞队列中的任务;

2、SHUTDOWN:关闭状态,不接收新任务,但可以继续处理阻塞队列中已有任务;

3、STOP:既不接收新任务,也不处理队列中的任务,并会中断正在处理的任务;

4、TIDYING(这个名字叫得有点奇怪):如果所有任务都已中止,且workCount有效线程数为0,则会调用terminated()方法进入TERMINATED状态;

5、TERMINATED:terminated()方法执行完后进入该状态,什么也不做。

 

线程池运行时的流程图:

 

 

 

 

至于线程池的构造函数什么的就不多啰嗦了,太枯燥无聊。

 


 

 

感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~

标签:Java,Worker,任务,ThreadPool,Manager,线程,new,多线程,public
From: https://www.cnblogs.com/xiangwang1111/p/16819778.html

相关文章

  • Java生产者消费者问题-多线程-线程同步-线程安全-线程通信
    packageA_ShangGuiGu.Thread.ThreadTest;/***生产者消费者问题:生产者(Producer)将商品(commodity)交给商店(Shop),消费者(Consumer)进行消费*商店里的商品数量上限为20......
  • java后台远程调用获取文件
    模拟本地服务为文件服务器(两种提供方式):假设本地文件为服务器,提供文件获取服务方法一:直接将输出流放入response里面作为响应@RequestMapping(value="/getUrlDownload",m......
  • java下载pdf等静态文件
    packagecom.example.climbnumber;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.URL;importjava.net......
  • 论 C++、C、Go 和 Java 的最大不同
     一、C++、C、Go中的如下语句:structxxx s1;vector<int>v;(甚至会调构造函数!)varABCsomeType其实会创建一个能用的对象!!、之后用他们进行操作......
  • 小白学习之路--java开发环境
    开发环境安装jdk市面企业主流还是jdk8我这就随便提供一个链接,网上实在是太多了,随便百度,面向百度编程jdk安装教程这个大佬写的挺全的IDE这个ide的话,我接触的有id......
  • Java异常的捕获和处理
    ......
  • 多测师肖sir____java自动化测试____基础介绍
    一、基础介绍1、为什么要做自动化测试(1)高级技能,发展趋势(2)提高代码的使用率(3)节省回归时间2、怎么去学习自动化测试(1)先学一门编程语言3、web自动化测试?定义:模拟手......
  • JAVA--LinkedList底层双链表添加元素超详细
     集合里面存储的都是对象    添加第一个元素    添加第二个元素    依次往后添加对象/元素。   first指向linkedList集合里存储的第......
  • 小白学习之路--java特性
    java特性总结一下java的特性简单性没啥好说的,它对c++进行再度封装,摒弃了c里面难懂的指针引用,还不用去分配内存,有了垃圾回收机制,不需要程序员手动回收内存面向对象......
  • 【Java】再说下Java多态中的向上转型和向下转型
    做比较多的服务端接口测试后,如果是http接口,使用jmeter、postman工具来测试都是比较方便的。如果是RPC接口,使用以上的工具就会比较吃力了。如果你对Java语言比较熟悉,建议可以......