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

[Java线程学习]Java线程新特征-线程池

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

    [LV.1]初来乍到

    发表于 2014-11-3 23:59:15 | 显示全部楼层 |阅读模式
    Sun在java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利。为了编写高效稳定可靠的多线程程序,线程部分的新增内容显得尤为重要。


      


    有关Java5线程新特征的内容全部在java.util.concurrent下面,里面包含数目众多的接口和类,熟悉这部分API特征是一项艰难的学习过程。目前有关这方面的资料和书籍都少之又少,大所属介绍线程方面书籍还停留在java5之前的知识层面上。


      


    当然新特征对做多线程程序没有必须的关系,在java5之前通用可以写出很优秀的多线程程序。只是代价不一样而已。


      


    线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。


      


    在Java5之前,要实现一个线程池是相当有难度的,现在Java5为我们做好了一切,我们只需要按照提供的API来使用,即可享受线程池带来的极大便利。


      


    Java5的线程池分好多种:固定尺寸的线程池、可变尺寸连接池、。


      


    在使用线程池之前,必须知道如何去创建一个线程池,在Java5中,需要了解的是java.util.concurrent.Executors类的API,这个类提供大量创建连接池的静态方法,是必须掌握的。


      


    一、固定大小的线程池


      


      
      
       import java.util.concurrent.Executors;
       

       import java.util.concurrent.ExecutorService;
       

       

       /**
    * Java线程:线程池-
    *
    * @author Administrator 2009-11-4 23:30:44
    */
       

       public
       class Test {
       
             
       public
       static
       void main(String[] args) {
       
                     
       //创建一个可重用固定线程数的线程池
       
                     ExecutorService pool = Executors.newFixedThreadPool(2);
       
                     
       //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
       
                     Thread t1 =
       new MyThread();
       
                     Thread t2 =
       new MyThread();
       
                     Thread t3 =
       new MyThread();
       
                     Thread t4 =
       new MyThread();
       
                     Thread t5 =
       new MyThread();
       
                     
       //将线程放入池中进行执行
       
                     pool.execute(t1);
       
                     pool.execute(t2);
       
                     pool.execute(t3);
       
                     pool.execute(t4);
       
                     pool.execute(t5);
       
                     
       //关闭线程池
       
                     pool.shutdown();
       
             }
       
    }
       

       

       class MyThread
       extends Thread{
       
             @Override
       
             
       public
       void run() {
       
                     System.out.println(Thread.currentThread().getName()+
       "正在执行。。。");
       
             }
       
    }
       
      


      


      
      
       pool-1-thread-1正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-2正在执行。。。
       

       
    Process finished with exit code 0
       
      


      


    二、单任务线程池


      


    在上例的基础上改一行创建pool对象的代码为:


      
       
       
                        
        //创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
       
                     ExecutorService pool = Executors.newSingleThreadExecutor();
       

       
       
      


      


    输出结果为:




      
      
       pool-1-thread-1正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-1正在执行。。。
       

       
    Process finished with exit code 0
       
      


      


    对于以上两种连接池,大小都是固定的,当要加入的池的线程(或者任务)超过池最大尺寸时候,则入此线程池需要排队等待。


    一旦池中有线程完毕,则排队等待的某个线程会入池执行。


      


    三、可变尺寸的线程池


      


    与上面的类似,只是改动下pool的创建方式:


      
      
                      
       //创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。
       
                     ExecutorService pool = Executors.newCachedThreadPool();
       

       
      


      


      
      
       pool-1-thread-5正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-4正在执行。。。
       
    pool-1-thread-3正在执行。。。
       
    pool-1-thread-2正在执行。。。
       

       
    Process finished with exit code 0
       
      


      


    四、延迟连接池


      


      
       
       
        import java.util.concurrent.Executors;
       

        import java.util.concurrent.ScheduledExecutorService;
       

        import java.util.concurrent.TimeUnit;
       

       

        /**
    * Java线程:线程池-
    *
    * @author Administrator 2009-11-4 23:30:44
    */
       

        public
        class Test {
       
             
        public
        static
        void main(String[] args) {
       
                     
        //创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
       
                     ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
       
                     
        //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
       
                     Thread t1 =
        new MyThread();
       
                     Thread t2 =
        new MyThread();
       
                     Thread t3 =
        new MyThread();
       
                     Thread t4 =
        new MyThread();
       
                     Thread t5 =
        new MyThread();
       
                     
        //将线程放入池中进行执行
       
                     pool.execute(t1);
       
                     pool.execute(t2);
       
                     pool.execute(t3);
       
                     
        //使用延迟执行风格的方法
       
                     pool.schedule(t4, 10, TimeUnit.MILLISECONDS);
       
                     pool.schedule(t5, 10, TimeUnit.MILLISECONDS);
       
                     
        //关闭线程池
       
                     pool.shutdown();
       
             }
       
    }
       

       

        class MyThread
        extends Thread {
       
             @Override
       
             
        public
        void run() {
       
                     System.out.println(Thread.currentThread().getName() +
        "正在执行。。。");
       
             }
       
    }
       
       
      


      


      
       
       
        pool-1-thread-1正在执行。。。
       
    pool-1-thread-2正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-2正在执行。。。
       

       
    Process finished with exit code 0
       
       
      


      


    五、单任务延迟连接池


      


    在四代码基础上,做改动



                      
      //创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
      
                     ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
      


      



      pool-1-thread-1正在执行。。。
      
    pool-1-thread-1正在执行。。。
      
    pool-1-thread-1正在执行。。。
      
    pool-1-thread-1正在执行。。。
      
    pool-1-thread-1正在执行。。。
      

      
    Process finished with exit code 0
      

      


      


    六、自定义线程池


      


      
      
       import java.util.concurrent.ArrayBlockingQueue;
       

       import java.util.concurrent.BlockingQueue;
       

       import java.util.concurrent.ThreadPoolExecutor;
       

       import java.util.concurrent.TimeUnit;
       

       

       /**
    * Java线程:线程池-自定义线程池
    *
    * @author Administrator 2009-11-4 23:30:44
    */
       

       public
       class Test {
       
             
       public
       static
       void main(String[] args) {
       
                     
       //创建等待队列
       
                     BlockingQueue<Runnable> bqueue =
       new ArrayBlockingQueue<Runnable>(20);
       
                     
       //创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
       
                     ThreadPoolExecutor pool =
       new ThreadPoolExecutor(2,3,2,TimeUnit.MILLISECONDS,bqueue);
       
                     
       //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
       
                     Thread t1 =
       new MyThread();
       
                     Thread t2 =
       new MyThread();
       
                     Thread t3 =
       new MyThread();
       
                     Thread t4 =
       new MyThread();
       
                     Thread t5 =
       new MyThread();
       
                     Thread t6 =
       new MyThread();
       
                     Thread t7 =
       new MyThread();
       
                     
       //将线程放入池中进行执行
       
                     pool.execute(t1);
       
                     pool.execute(t2);
       
                     pool.execute(t3);
       
                     pool.execute(t4);
       
                     pool.execute(t5);
       
                     pool.execute(t6);
       
                     pool.execute(t7);
       
                     
       //关闭线程池
       
                     pool.shutdown();
       
             }
       
    }
       

       

       class MyThread
       extends Thread {
       
             @Override
       
             
       public
       void run() {
       
                     System.out.println(Thread.currentThread().getName() +
       "正在执行。。。");
       
                     
       try {
       
                             Thread.sleep(100L);
       
                     }
       catch (InterruptedException e) {
       
                             e.printStackTrace();
       
                     }
       
             }
       
    }
       
      



      
      
       pool-1-thread-1正在执行。。。
       
    pool-1-thread-2正在执行。。。
       
    pool-1-thread-2正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-2正在执行。。。
       
    pool-1-thread-1正在执行。。。
       
    pool-1-thread-2正在执行。。。
       

       
    Process finished with exit code 0
       
      


      


    创建自定义线程池的构造方法很多,本例中参数的含义如下:


      
       
       ThreadPoolExecutor
      
    1. public [b]ThreadPoolExecutor[/b](int corePoolSize,
    2.                           int maximumPoolSize,
    3.                           long keepAliveTime,
    4.                           [url=mk:@MSITStore:F:CHMjdk150.ZH_cn.chm::/jdk150/api/java/util/concurrent/TimeUnit.html]TimeUnit[/url] unit,
    5.                           [url=mk:@MSITStore:F:CHMjdk150.ZH_cn.chm::/jdk150/api/java/util/concurrent/BlockingQueue.html]BlockingQueue[/url]<[url=mk:@MSITStore:F:CHMjdk150.ZH_cn.chm::/jdk150/api/java/lang/Runnable.html]Runnable[/url]> workQueue)
    复制代码

       
       
         用给定的初始参数和默认的线程工厂及处理程序创建新的
         ThreadPoolExecutor。使用
         
    1. Executors
    复制代码
    工厂方法之一比使用此通用构造方法方便得多。
          
          
          
            参数:
          
          
          
    1. corePoolSize
    复制代码
    - 池中所保存的线程数,包括空闲线程。
          
          
          
    1. maximumPoolSize
    复制代码
    - 池中允许的最大线程数。
          
          
          
    1. keepAliveTime
    复制代码
    - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
          
          
          
    1. unit
    复制代码
    - keepAliveTime 参数的时间单位。
          
          
          
    1. workQueue
    复制代码
    - 执行前用于保持任务的队列。此队列仅保持由
            execute 方法提交的
            Runnable 任务。
          
          
            抛出:
          
          
          
    1. [url=mk:@MSITStore:F:CHMjdk150.ZH_cn.chm::/jdk150/api/java/lang/IllegalArgumentException.html]IllegalArgumentException[/url]
    复制代码
    - 如果 corePoolSize 或 keepAliveTime 小于零,或者 maximumPoolSize 小于或等于零,或者 corePoolSize 大于 maximumPoolSize。
          
          
          
    1. [url=mk:@MSITStore:F:CHMjdk150.ZH_cn.chm::/jdk150/api/java/lang/NullPointerException.html]NullPointerException[/url]
    复制代码
    - 如果
            workQueue 为 null
            
          
          
         
       
       
      


      


    自定义连接池稍微麻烦些,不过通过创建的ThreadPoolExecutor线程池对象,可以获取到当前线程池的尺寸、正在执行任务的线程数、工作队列等等。


      


    有关Java5线程池的内容到此就没有了,更多的内容还需要研读API来获取。

    出处http://lavasoft.blog.51cto.com/62575/222078




      
      
       
       

         
       

         
       
      
    复制代码
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2025-2-25 13:52 , Processed in 0.357514 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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