java自带线程池的简单使用

之前我们有学习过java的线程,但我们知道,进程才是系统分配资源的最小单位。实际使用过程中,比如我们打开了浏览器,它会对应启动多个进程。而每个进程中又包含着多个线程。那也就是说,实际工作使用时,很少会使用单个的线程来完成某项任务。那对于很多线程使用的情况,我们应该怎么合理的节省系统资源呢?
于是在这里引入了线程池的概念。那什么是线程池呢?通俗来讲,就是一个存放线程的容器。java5之后,java引入了自带的线程池管理框架Executor,今天我们简单介绍下这个框架的使用。

为什么使用线程池

假设每条线程的创建时间为t1,线程工作时间为t2,线程销毁时间为t3.那如果处理器每天处理的线程数是50000,那不使用线程池的时候,需要花费的时间为50000(t1+t2+t3),而假设我们使用了一个合适容量的线程池,那么我们就省去了t1和t3的时间,提高了处理器的利用率(这说法不完全准确,需要结合处理器性能,系统设计等实际情况去比对)。可以这样说:如果:t1 + t3 远大于 t2,则可以采用线程池,以提高服务器性能。

常用的线程池类型及简单实现

  • singleThreadExecutor
    可以创建只含有一条线程的线程池。如果需要多条线程完成任务,则任务需要依次执行。请参见代码:
    /**
     * newSingleThreadExecutor创建只有一条线程的线程池
     * 所以在执行线程时,虽然用线程池加载了三个线程对象,但由于线程池只有一条线程,所以输出结果是三个线程依次执行
     */
    public void singleThread(){
        //通过Executors工具类 的newSingleThreadExecutor方法创建线程池
        ExecutorService e=Executors.newSingleThreadExecutor();

        //创建线程对象
        Thread t1=new Thread(new RunnableDemo("why"));
        Thread t2=new Thread(new RunnableDemo("sb"));
        Thread t3=new Thread(new RunnableDemo("zzh"));

        //使用线程池调度线程
        e.execute(t1);  
        e.execute(t2);
        e.execute(t3);

        //关闭线程池
        e.shutdown();
    }
  • FixedThreadPool
    创建含有固定条数线程的线程池。具体使用参见下例:
    /**
     * newFixedThreadPool(int num)  该方法会按照用户指定的数据创建固定线程数的线程池。如下例为3
     * 所以在使用的时候,若需要的线程数不大于3时,线程池会自动分配线程,执行操作。若超出3(线程池最大线程数),则需要前面占用线程释放后,才会执行后面的线程计划
     */
    public void fixedThread(){
        //通过Executors工具类 的newFixedThreadPool方法创建线程池
        ExecutorService e =Executors.newFixedThreadPool(3); //指定线程池线程数为3

        //创建线程对象
        Thread t1=new Thread(new RunnableDemo("why"));
        Thread t2=new Thread(new RunnableDemo("sb"));
        Thread t3=new Thread(new RunnableDemo("zzh"));
        Thread t4=new Thread(new RunnableDemo("aiguo"));

        //使用线程池调度线程
        e.execute(t1);  
        e.execute(t2);
        e.execute(t3);
        e.execute(t4);

        //关闭线程池
        e.shutdown();       
    }
  • CachedThreadPool

创建一个可缓存的线程池。线程池中的线程数可以按照实际需求自行调整。

/**
     * newCachedThreadPool()可以创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,
     * 那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。
     * 此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
     */
    public void cacheThread(){
        //通过Executors工具类 的newCachedThreadPool方法创建线程池
        ExecutorService e =Executors.newCachedThreadPool();

        //创建线程对象
        Thread t1=new Thread(new RunnableDemo("why"));
        Thread t2=new Thread(new RunnableDemo("sb"));
        Thread t3=new Thread(new RunnableDemo("zzh"));
        Thread t4=new Thread(new RunnableDemo("aiguo"));

        //使用线程池调度线程
        e.execute(t1);  
        e.execute(t2);
        e.execute(t3);
        e.execute(t4);

        //关闭线程池
        e.shutdown();       
    }
  • ScheduledThreadPool

创建一个定时执行的线程池。一般来说推荐使用上面三种,这种很少使用。

/**
     * 使用ScheduledThreadPoolExecutor来构造线程池 (很少使用)
     *  1.固定频率来执行指定操作
     */
    public void scheduleThread(){
        ScheduledThreadPoolExecutor e=new ScheduledThreadPoolExecutor(1);   //指定线程池中的线程数。若线程数小于需要线程数,则需要等待前面线程执行完成后再执行
        e.scheduleAtFixedRate(new RunnableDemo("why"), 1000, 1000, TimeUnit.MILLISECONDS);//构造参数为:(进程,初始时间,间隔时间,时间单位)
        e.scheduleAtFixedRate(new RunnableDemo("sb"), 1000, 5000, TimeUnit.MILLISECONDS);
    }

ThreadPoolExecutor详解(扩展内容,有兴趣的可以去查阅源码)

ThreadPoolExecutor的完整构造方法的签名是:ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) .

corePoolSize - 池中所保存的线程数,包括空闲线程。

maximumPoolSize-池中允许的最大线程数。

keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。

unit - keepAliveTime 参数的时间单位。

workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute方法提交的 Runnable任务。

threadFactory - 执行程序创建新线程时使用的工厂。

handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。

ThreadPoolExecutor是Executors类的底层实现。

在JDK帮助文档中,有如此一段话:

“强烈建议程序员使用较为方便的Executors工厂方法Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池)Executors.newSingleThreadExecutor()(单个后台线程),它们均为大多数使用场景预定义了设置。”

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值