您的位置:首页 > 其它

线程池

2015-11-04 12:32 381 查看

线程池的由来

线程池是线程管理的地方,因为线程的创建和回收很浪费系统资源,而线程池为线程生命周期开销问题和资源不足问题提供了解决方案。

1.因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快

2.通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。

分类

1.固定大小的线程池

Executors.newFixedThreadPool(number)

会根据数字number来创建指定大小的线程池

import java.util.concurrent.Executors;
  import java.util.concurrent.ExecutorService;

  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正在执行。。。

会从创建的线程池中选取空闲的线程来执行

2.单任务线程池

创建一个使用单个 worker 线程的线程池,以无界队列方式来运行该线程。

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

ExecutorService pool = Executors.newSingleThreadExecutor();


 

  执行结果

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

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

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

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

从创建的线程池中选取线程执行,如无空闲则不等待

3.可变尺寸的线程池

 

创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。

与上面的类似,只是改动下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正在执行。。。

会根据实际需要创建线程,无需等待。

4.固定大小计划连接池

//创建一个制定大小的延迟线程池,它可安排在给定延迟后运行命令或者定期地执行。

import java.util.concurrent.Executors;
  import java.util.concurrent.ScheduledExecutorService;
  import java.util.concurrent.TimeUnit;
  
  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正在执行。。。

跟类1基本一致,不同在于可延迟启动

5.单任务计划线程池

  在4.基础上,做改动

创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。

ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();


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

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

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

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

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

跟2.基本一致,不同在于可延迟执行

6.自定义线程池

import java.util.concurrent.ArrayBlockingQueue;
  import java.util.concurrent.BlockingQueue;
  import java.util.concurrent.ThreadPoolExecutor;
  import java.util.concurrent.TimeUnit;

  public class Test {
  public static void main(String[] args) {
  //创建等待队列
  BlockingQueue bqueue = new ArrayBlockingQueue(20);
  
  //创建一个线程执行程序,它可安排在给定延迟后执行或者定期地执行。
  ThreadPoolExecutor pool = new ThreadPoolExecutor(2,3,2000,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正在执行。。。

根据ThreadPoolExecutor设置的参数创建自定义线程

给出ThreadPoolExecutor的API

public ThreadPoolExecutor(int corePoolSize,
  int maximumPoolSize,
  long keepAliveTime,
  TimeUnit unit,
  BlockingQueue workQueue)


  参数:

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

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

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

  unit - keepAliveTime 参数的时间单位。

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

  PS:线程池shutdown后必须重新申请线程池,否则会抛出异常IllegalArgumentException

  

整理自:http://zy116494718.iteye.com/blog/1704344
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线程池 线程