热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

生成者与消费者线程池及线程池资源比较

前言前一阵去华为面试。技术面中,我提到平时常用的线程池为依据生成者-消费者关系写的线程池,较少使用Java-Executors的线程池,面试官疑问JAVA线程池不好用?我竟大言不惭的说JA

前言

前一阵去华为面试。技术面中,我提到平时常用的线程池为依据生成者-消费者关系写的线程池,较少使用Java-Executors的线程池,面试官疑问JAVA线程池不好用?我竟大言不惭的说JAVA线程池耗费资源,面试管的那个鄙视眼神,至今未忘怀^_^。

  • 生产者与消费者线程池详解
  • 耗费的资源是-线程切换

生成者与消费者线程池

概念在此不做介绍,不懂就不懂吧!
字面意思很容易理解撒,生成者生成产品,消费者消费产品,生成者,消费者均可以多个。你会说这和线程池有个diao关系。别急嘛,给大爷您笑个,整理整理心情再向下看。
例子来了:隔壁老王种了一棵苹果树成熟了,一树的苹果么有办法卖,就存在自家仓库,供自家人吃,当然还有隔壁胖红。
理解没?没理解再瞅这:苹果树-生成者。胖红等人-消费者。仓库呢,就是TMD池。胖红等不就是执行的常驻线程。苹果树就是资源的产生者,产生的资源(苹果)放入池(仓库)中,常驻线程消费者(胖红等人)消费资源。如果还没看懂,为您的智商表示担忧,还是建议你学好spring就够。

nounou上代码

代码仅是随手写的样例,不过向天发誓展示代码完整

消费者,由资源池tasks中取出资源task ,并对资源进行消费task.execute()


import java.util.concurrent.BlockingQueue;
//我是消费者
public class ExecutTread extends Thread{

    public ExecutTread(BlockingQueue tasks) {

        this.tasks = tasks;//我是所有消费线程共享的资源池
    }
    BlockingQueue tasks = null;

    volatile boolean run = true;

    volatile boolean busy = false;
    //AtomicBoolean busy = new AtomicBoolean(false);

    @Override
    public void run() {
        // TODO Auto-generated method stub

        //此处证明我的饭量不错
        while(run) {

            //取资源
            AbstractTask task = tasks.poll();

            if(task == null) {

                ThreadCompare.waitIt(5);
                continue;
            }
            busy = true;
            try {
                //消费资源
                task.execute();
            } finally {
                busy = false;
            }
        }
    }
}

该看看资源是个什么鸟

//我就是那个鸟,资源的爹
public abstract class AbstractTask {

    abstract void execute();
}

看了半天,该骂爹了,说好的池呢,资源池炒好了,退不了了

package com.ccycc.rxjava.rxjavaL;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import com.google.common.collect.Lists;

public class ThreadManager {

    //我tasks 就是传说中的资源池 大跌眼镜啊
    BlockingQueue tasks = new LinkedBlockingQueue(); 
    List treads = Lists.newArrayList();

    //初始化消费者线程
    void init() {

        for(int i=0; i<10; i++) {

            ExecutTread tread = new ExecutTread(tasks);
            tread.start();
            treads.add(tread);
        }
    }
    //我只是向池中放资源的动作
    void addTask(AbstractTask task) {

        tasks.offer(task);
    }
    boolean isfinsih() {

        if(tasks.size() > 0) {

            return false;
        }
        for(ExecutTread tread :treads) {

            if(tread.busy) {

                return false;
            }
        }
        return true;
    }
}

好了生产者与消费的线程池完了,哎卧槽,生成者呢?看着也不像个线程池啊?线程池连个线程都么有。您试着将消费者线程强加到池里。有个池子,他里面由几个工作线程,把资源执行完和线程池里放很多线程,线程里包装资源不差不多道理。呵呵!
再看看:

package com.ccycc.rxjava.rxjavaL;

public class WorkTask extends AbstractTask{
    //资源要执行的业务
    @Override
    void execute() {
        // TODO Auto-generated method stub
        try {
            Thread.sleep(10);
            //System.out.println("*****");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
//
void cpthreadpool() {

        ThreadManager manager = new ThreadManager();

        long start = System.currentTimeMillis();
        //在这初始化消费者
        manager.init();
        int i=0;
        //在这生成资源
        for(;i<1000000;i++) {

            manager.addTask(new WorkTask());
        }
        while(true) {

            if(!manager.isfinsih()) {

                waitIt(500);
            }else {

                break;
            }
        }
        System.out.println("总耗时:" + ((System.currentTimeMillis() - start)/1000));
    }

最后,有人会说这垃圾的池,啥功能都么有,人家java-Exectors中的有各种策略,比如拒绝,超时了什么的。^_^不好意思,忘记了如果你能看到这,估计八成也不清楚那四种策略,罪过。

线程耗费资源

这是一个打脸的话题,java-Exectors的线程池,没有这破玩意牛逼?那当然不是,当然不是,当然不是。重要的话说三遍。因为我耿耿于怀华为面试人那个鄙视的眼神。我是来证明线程切换真真的耗费资源。不过么有那么严重的说,实时证明是几乎无感知,呵呵,前后矛盾,自己打自己脸,看测试结果吧。

package com.ccycc.rxjava.rxjavaL;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadCompare {

    public static void main(String[] args) {

        ThreadCompare compare = new ThreadCompare();
        //compare.javathreadpool();
        compare.cpthreadpool();
    }
    //这个是java线程池
    void javathreadpool() {

        ExecutorService service = Executors.newFixedThreadPool(10);
        int i=0;
        long start = System.currentTimeMillis();
        for(;i<1000000;i++) {

            service.submit(new Worker());
        }
        service.shutdown();
        while(true) {

            if(!service.isTerminated()) {

                waitIt(500);
            }else {
                break;
            }
        }

        System.out.println("总耗时:" + ((System.currentTimeMillis() - start)/1000));
    }
    //这个是生成者与消费者的线程池
    void cpthreadpool() {

        ThreadManager manager = new ThreadManager();

        long start = System.currentTimeMillis();
        manager.init();
        int i=0;
        for(;i<1000000;i++) {

            manager.addTask(new WorkTask());
        }
        while(true) {

            if(!manager.isfinsih()) {

                waitIt(500);
            }else {

                break;
            }
        }
        System.out.println("总耗时:" + ((System.currentTimeMillis() - start)/1000));
    }
    static void waitIt(long timeout) {

        try {
            Thread.sleep(timeout);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

package com.ccycc.rxjava.rxjavaL;

public class Worker extends Thread{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            Thread.sleep(10);
            //System.out.println("*****");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

java线程池执行耗时:1037秒。
生成者与消费者线程池耗时:1031秒。

结果当然是支持我的,哎!重要的事情粗体线程切换耗费资源,上面的例子也只是为了证实这个概念。
到此可能还有人不懂?一脸懵逼。生成者与消费者线程池是不是仅有10个线程。java-Exectors种全部不都是线程,一个线程干完活,是不是要切换另一个线程。对,就是这。

转载请注明来源

欢迎大家沟通交流
这里写图片描述


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 标题: ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 基于移动平台的会展导游系统APP设计与实现的技术介绍与需求分析
    本文介绍了基于移动平台的会展导游系统APP的设计与实现过程。首先,对会展经济和移动互联网的概念进行了简要介绍,并阐述了将会展引入移动互联网的意义。接着,对基础技术进行了介绍,包括百度云开发环境、安卓系统和近场通讯技术。然后,进行了用户需求分析和系统需求分析,并提出了系统界面运行流畅和第三方授权等需求。最后,对系统的概要设计进行了详细阐述,包括系统前端设计和交互与原型设计。本文对基于移动平台的会展导游系统APP的设计与实现提供了技术支持和需求分析。 ... [详细]
  • springboot启动不了_Spring Boot + MyBatis 多模块搭建教程
    作者:枫本非凡来源:www.cnblogs.comorzlinp9717399.html一、前言1、创建父工程最近公司项目准备开始重构,框 ... [详细]
  • 我所理解的JMM 2 new原子性
    概述文本探讨构造函数是否为原子性问题。案例我们首先如下代码:publicclassPerson{publicintage;publicPerson(){age ... [详细]
  • Java编程思想一书中第21章并发中关于线程间协作的一节中有个关于汽车打蜡与抛光的小例子(原书的704页)。这个例子主要展示的是两个线程如何通过wait ... [详细]
  • 作者一直强调的一个概念叫做oneloopperthread,撇开多线程不谈,本篇博文将学习,怎么将传统的IO复用pollepoll封装到C++类中。1.IO复用复习使用p ... [详细]
author-avatar
鸟鸟212
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有