Java线程池

简介: Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利。为了编写高效稳定可靠的多线程程序,线程部分的新增内容显得尤为重要。  有关Java5线程新特征的内容全部在java.util.concurrent下面,里面包含数目众多的接口和类,熟悉这部分API特征是一项艰难的学习过程。目前有
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 bqueue = new ArrayBlockingQueue(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 
  public ThreadPoolExecutor(int corePoolSize, 
  int maximumPoolSize, 
  long keepAliveTime, 
  TimeUnit unit, 
  BlockingQueue workQueue) 


  用给定的初始参数和默认的线程工厂及处理程序创建新的 ThreadPoolExecutor。使用 Executors 工厂方法之一比使用此通用构造方法方便得多。

  参数:

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

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

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

  unit - keepAliveTime 参数的时间单位。

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

  抛出:

  IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小于零,或者 maximumPoolSize 小于或等于零,或者 corePoolSize 大于 maximumPoolSize。

  NullPointerException - 如果 workQueue 为 null

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

  有关Java5线程池的内容到此就没有了,更多的内容还需要研读API来获取。
目录
相关文章
|
20天前
|
Java 调度
Java并发编程:深入理解线程池的原理与实践
【4月更文挑战第6天】本文将深入探讨Java并发编程中的重要概念——线程池。我们将从线程池的基本原理入手,逐步解析其工作过程,以及如何在实际开发中合理使用线程池以提高程序性能。同时,我们还将关注线程池的一些高级特性,如自定义线程工厂、拒绝策略等,以帮助读者更好地掌握线程池的使用技巧。
|
28天前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
52 1
|
23天前
|
Java
深入理解Java并发编程:线程池的应用与优化
【4月更文挑战第3天】 在Java并发编程中,线程池是一种重要的资源管理工具,它能有效地控制和管理线程的数量,提高系统性能。本文将深入探讨Java线程池的工作原理、应用场景以及优化策略,帮助读者更好地理解和应用线程池。
|
18天前
|
Java
Java 并发编程:深入理解线程池
【4月更文挑战第8天】本文将深入探讨 Java 中的线程池技术,包括其工作原理、优势以及如何使用。线程池是 Java 并发编程的重要工具,它可以有效地管理和控制线程的执行,提高系统性能。通过本文的学习,读者将对线程池有更深入的理解,并能在实际开发中灵活运用。
|
1月前
|
监控 Java
Java并发编程中的线程池优化技巧
在Java并发编程中,线程池扮演着至关重要的角色。本文将深入探讨如何优化Java线程池,从线程池的创建与配置、任务队列的选择、拒绝策略的制定、线程池状态的监控等多个方面进行详细阐述。通过本文的阅读,您将了解到如何合理地利用线程池,提高系统的并发性能,从而更好地应对各种并发场景。
|
19天前
|
Java
Java并发编程:深入理解线程池
【4月更文挑战第7天】在现代软件开发中,多线程编程已经成为一种不可或缺的技术。为了提高程序性能和资源利用率,Java提供了线程池这一强大工具。本文将深入探讨Java线程池的原理、使用方法以及如何根据实际需求定制线程池,帮助读者更好地理解和应用线程池技术。
15 0
|
3天前
|
Java
Java中的并发编程:理解和应用线程池
【4月更文挑战第23天】在现代的Java应用程序中,性能和资源的有效利用已经成为了一个重要的考量因素。并发编程是提高应用程序性能的关键手段之一,而线程池则是实现高效并发的重要工具。本文将深入探讨Java中的线程池,包括其基本原理、优势、以及如何在实际开发中有效地使用线程池。我们将通过实例和代码片段,帮助读者理解线程池的概念,并学习如何在Java应用中合理地使用线程池。
|
9天前
|
缓存 分布式计算 监控
Java并发编程:深入理解线程池
【4月更文挑战第17天】在Java并发编程中,线程池是一种非常重要的技术,它可以有效地管理和控制线程的执行,提高系统的性能和稳定性。本文将深入探讨Java线程池的工作原理,使用方法以及在实际开发中的应用场景,帮助读者更好地理解和使用Java线程池。
|
10天前
|
存储 缓存 监控
Java线程池
Java线程池
48 1
|
10天前
|
缓存 监控 Java
Java并发编程:线程池与任务调度
【4月更文挑战第16天】Java并发编程中,线程池和任务调度是核心概念,能提升系统性能和响应速度。线程池通过重用线程减少创建销毁开销,如`ThreadPoolExecutor`和`ScheduledThreadPoolExecutor`。任务调度允许立即或延迟执行任务,具有灵活性。最佳实践包括合理配置线程池大小、避免过度使用线程、及时关闭线程池和处理异常。掌握这些能有效管理并发任务,避免性能瓶颈。