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入门到精通教程
查看: 375|回复: 0

[Java线程学习]使用线程池处理简短任务

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

    [LV.1]初来乍到

    发表于 2014-10-28 23:56:48 | 显示全部楼层 |阅读模式
    java程序中要用线程处理多个简短任务的时候,使用一种叫做Thread Pooling的技术是很明智的选择。为了不对单个任务逐个创建(并在任务结束时结束)线程,过去我们经常自己编写适合不同运行环境需要的线程池。虽然这些线程池的具体属性参数不尽相同,但是大致都追寻着如下的应用套式:

    把任务组引入到线程池里面,
    如果线程池中某个线程满足执行条件,立刻执行
    任务执行完毕,线程返回线程池
    不满足执行条件(比如线程池大小条件),等待执行

    J2SE5.0现在提供了全新的java.util.concurrent包,其中有几经构建好的线程池的框架。

    例如:Executor接口提供了单独的一个办法execute来接收一个Runnable的实例对象:
    public interface Executor {
         public void execute(Runnable command);
    }
       
      
       
       
       

       
      
    所以我们可以创建一个Executor对象 然后把runnable任务引入:

    Executor executor = ...; //可以完成implements后创建...
    executor.execute(aRunnable1);
    executor.execute(aRunnable2);

    例如:

    class MyExecutor implements Executor {
        public void execute(Runnable r) {
           new Thread(r).start();
        }
    }

          在concurrency中还包括一个ThreadPoolExecutor类来提供一般通用用途的线程池操作.下面是4种该类的构造器.我们可以确定该类的某些属性例如: 池的大小,活动时间,线程工厂和被拒绝运行线程控制器.
      

    1.   public ThreadPoolExecutor(int corePoolSize,
    2.                              int maximumPoolSize,
    3.                              long keepAliveTime,
    4.                              TimeUnit unit,
    5.                              BlockingQueue
    6.    workQueue)
    7.    public ThreadPoolExecutor(int corePoolSize,
    8.                              int maximumPoolSize,
    9.                              long keepAliveTime,
    10.                              TimeUnit unit,
    11.                              BlockingQueue
    12.    workQueue,
    13.                              ThreadFactory threadFactory)
    14.    public ThreadPoolExecutor(int corePoolSize,
    15.                              int maximumPoolSize,
    16.                              long keepAliveTime,
    17.                              TimeUnit unit,
    18.                              BlockingQueue
    19.    workQueue,
    20.                              RejectedExecutionHandler handler)
    21.    public ThreadPoolExecutor(int corePoolSize,
    22.                              int maximumPoolSize,
    23.                              long keepAliveTime,
    24.                              TimeUnit unit,
    25.                              BlockingQueue
    26.    workQueue,
    27.                              ThreadFactory threadFactory,
    28.                              RejectedExecutionHandler handler)
    复制代码



            其实我们实际使用线程池的时候并不需要用构造器来专门建立上面的ThreadPoolExecutor的对象.Executors类中已经创建了默认的线程池.例如我们可以在Executors中调用newFixedThreadPool办法规定你需要的线程池的大小.可以使用一个继承了Executor的ExectuorService类来运行或者提交Runnalbe任务组. ExectuorService的提交办法 -- submit 允许得到一个结果F, 而且返回FUTURE OBJECT,可以用来检查是否任务已经执行完毕.
    下面是一个具体的应用实例: -- 摘自sun技术论坛


    1.    
    2.      public class NamePrinter implements Runnable {
    3.      private final String name;
    4.      private final int delay;
    5.      public NamePrinter(String name, int delay) {
    6.        this.name = name;
    7.        this.delay = delay;
    8.      }
    9.      public void run() {
    10.        System.out.println("Starting: " + name);
    11.        try {
    12.          Thread.sleep(delay);
    13.        } catch (InterruptedException ignored) {
    14.        }
    15.        System.out.println("Done with: " + name);
    16.      }
    17.    }
    18. ----------------------------------------------------------------------------------
    19.    import java.util.concurrent.*;
    20.    import java.util.Random;
    21.    public class UsePool {
    22.      public static void main(String args[]) {
    23.        Random random = new Random();
    24.        ExecutorService executor =
    25.                Executors.newFixedThreadPool(3); //设定线程池容量为3
    26.        // Sum up wait times to know when to shutdown
    27.        int waitTime = 500;
    28.        for (int i=0; i<10; i++) {
    29.          String name = "NamePrinter " + i;
    30.          int time = random.nextInt(1000);
    31.          waitTime += time;
    32.          Runnable runner = new NamePrinter(name, time);
    33.          System.out.println("Adding: " + name + " / " + time);
    34.          executor.execute(runner);
    35.        }
    36.        try {
    37.          Thread.sleep(waitTime);
    38.          executor.shutdown();
    39.          executor.awaitTermination
    40.                  (waitTime, TimeUnit.MILLISECONDS);
    41.        } catch (InterruptedException ignored) {
    42.        }
    43.        System.exit(0);
    44.      }
    45.     }
    46. ----------------------------------------------------------------------------------
    47. 可能输出:
    48. unique with the random sleeps present:
    49.    Adding: NamePrinter 0 / 30
    50.    Adding: NamePrinter 1 / 727
    51.    Adding: NamePrinter 2 / 980  //前3个添加进行的明显比较快
    52.    Starting: NamePrinter 0
    53.    Starting: NamePrinter 1
    54.    Starting: NamePrinter 2
    55.    Adding: NamePrinter 3 / 409
    56.    Adding: NamePrinter 4 / 49
    57.    Adding: NamePrinter 5 / 802
    58.    Adding: NamePrinter 6 / 211
    59.    Adding: NamePrinter 7 / 459
    60.    Adding: NamePrinter 8 / 994
    61.    Adding: NamePrinter 9 / 459
    62.    Done with: NamePrinter 0    虽然任务全部已经添加到线程池,
    63.    Starting: NamePrinter 3     但是因为线程池容量为3个,
    64.    Done with: NamePrinter 3    前3个任务又都在执行,
    65.    Starting: NamePrinter 4     所以任务3一直等到任务0结束才开始执行
    66.    Done with: NamePrinter 4
    67.    Starting: NamePrinter 5
    68.    Done with: NamePrinter 1
    69.    Starting: NamePrinter 6
    70.    Done with: NamePrinter 6
    71.    Starting: NamePrinter 7
    72.    Done with: NamePrinter 2
    73.    Starting: NamePrinter 8
    74.    Done with: NamePrinter 5
    75.    Starting: NamePrinter 9
    76.    Done with: NamePrinter 7
    77.    Done with: NamePrinter 9
    78.    Done with: NamePrinter 8

    79.   线程池框架中还有很多其它的内容,请参考api. _
    复制代码



      
      
       
       

         
       

         
       
      



    源码下载:http://file.javaxxz.com/2014/10/28/235647750.zip
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2025-2-26 02:02 , Processed in 0.365470 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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