为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Java

您好,我是湘王,这是我的慕课手记,欢迎您来,欢迎您再来~



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

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

1、T1:创建启动

2、T2:运行行驶

3、T3:销毁停车

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

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

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

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

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

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

https://img1.sycdn.imooc.com//63554cd50001051309840524.jpg 

 

很多人都分不清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()方法执行完后进入该状态,什么也不做

 

线程池运行时的流程图

https://img1.sycdn.imooc.com//63554cf50001de7208740245.jpg

 

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

https://img1.sycdn.imooc.com//63554cfa0001166807750603.jpg



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



点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消