Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 286|回复: 0

[Java线程学习]jdk1.5中的线程池使用简介

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-5 00:00:00 | 显示全部楼层 |阅读模式
    一、简介
          线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
    long keepAliveTime, TimeUnit unit,
    BlockingQueue workQueue,
    RejectedExecutionHandler handler) corePoolSize: 线程池维护线程的最少数量
    maximumPoolSize:线程池维护线程的最大数量
    keepAliveTime: 线程池维护线程所允许的空闲时间
    unit: 线程池维护线程所允许的空闲时间的单位
    workQueue: 线程池所使用的缓冲队列
    handler: 线程池对拒绝任务的处理策略
      
       
       
         
       

         
       
      
            一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。 当一个任务通过execute(Runnable)方法欲添加到线程池时:      如果此时线程池中线程的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。     如果此时线程池中线程的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。     如果此时线程池中线程的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的线程数量小于maximumPoolSize,建新的线程来处理被添加的任务。      如果此时线程池中线程的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。 也就是:处理任务的优先级为:
    核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。 unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
    NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。 workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue handler有四个选择:
    ThreadPoolExecutor.AbortPolicy()
    抛出java.util.concurrent.RejectedExecutionException异常

    ThreadPoolExecutor.CallerRunsPolicy()
    重试添加当前的任务,他会自动重复调用execute()方法

    ThreadPoolExecutor.DiscardOldestPolicy()
    抛弃旧的任务

    ThreadPoolExecutor.DiscardPolicy()
    抛弃当前的任务 二、一般用法举例
    1. import java.io.Serializable;
    2. import java.util.concurrent.ArrayBlockingQueue;
    3. import java.util.concurrent.ThreadPoolExecutor;
    4. import java.util.concurrent.TimeUnit;
    5. public class TestThreadPool {
    6. private static int produceTaskSleepTime = 2;
    7. private static int consumeTaskSleepTime = 2000;
    8. private static int produceTaskMaxNumber = 10;

    9. public static void main(String[] args) {
    10. //构造一个线程池
    11. ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,TimeUnit.SECONDS,
    12.         new ArrayBlockingQueue(3),new ThreadPoolExecutor.CallerRunsPolicy());
    13. for(int i=1;i<=produceTaskMaxNumber;i++){
    14.   try {
    15.    //产生一个任务,并将其加入到线程池
    16.     String task = "task@ " + i;
    17.     System.out.println("put " + task);
    18.     threadPool.execute(new ThreadPoolTask(task));
    19.     //便于观察,等待一段时间
    20.     Thread.sleep(produceTaskSleepTime);
    21.   } catch (Exception e) {
    22.     e.printStackTrace();
    23.   }
    24. }
    25. }
    26. /**
    27. 线程池执行的任务
    28. @author hdpan
    29. */
    30. public static class ThreadPoolTask implements Runnable,Serializable{
    31.   private static final long serialVersionUID = 0;
    32.   //保存任务所需要的数据
    33.   private Object threadPoolTaskData;
    34. ThreadPoolTask(Object tasks){
    35.   this.threadPoolTaskData = tasks;
    36. }
    37. public void run(){
    38.   //处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句
    39.   System.out.println("start ..."+threadPoolTaskData);
    40.   try {
    41.     ////便于观察,等待一段时间
    42.     Thread.sleep(consumeTaskSleepTime);
    43.    } catch (Exception e) {
    44.     e.printStackTrace();
    45.   }
    46.   threadPoolTaskData = null;
    47. }
    48. public Object getTask(){
    49.   return this.threadPoolTaskData;
    50. }
    51. }
    52. }
    复制代码
    运行结果: C:java>java TestThreadPool
    put task@ 1
    start ...task@ 1
    put task@ 2
    start ...task@ 2
    put task@ 3
    put task@ 4
    put task@ 5
    put task@ 6
    start ...task@ 3
    put task@ 7
    start ...task@ 4
    put task@ 8
    start ...task@ 8
    start ...task@ 5
    start ...task@ 6
    start ...task@ 7
    put task@ 9
    start ...task@ 9
    put task@ 10
    start ...task@ 10
      // ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― 说明:
    1、在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。 2、一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。 3、在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。 这个小组里面队员至少有两个,如果他们两个忙不过来, 任务就被放到任务列表里面。 如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员, 至多只能雇佣 4个。 如果四个队员都在忙时,再有新的任务, 这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发, 直到接受这个任务为止(更残忍!呵呵)。 因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。 4、通过调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制, 改变这两个值就可以观察不同速率下程序的工作情况。 5、通过调整4中所指的数据,再加上调整任务丢弃策略, 换上其他三种策略,就可以看出不同策略下的不同处理方式。 6、对于其他的使用方法,参看jdk的帮助,很容易理解和使用。  

      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/11/4/235959328.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 13:41 , Processed in 0.345847 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表