Java中如何合理利用线程池,有什么好处-软件教程-学码思教育
全国热线

025-86901720

全国监督投诉热线:9:00-23:00

Java中如何合理利用线程池,有什么好处

关于Java中如何利用线程池,有什么好处,今天就让南京学码思Java培训机构​老师来为大家分析解答一下。

学习Java开发的过程中,线程池也是重要内容之一,学习并掌握好线程池相关内容是需要每位学员考虑的方面。关于Java中如何利用线程池,有什么好处,今天就让南京学码思Java培训机构老师来为大家分析解答一下。

Java中如何合理利用线程池,有什么好处

1. 合理利用线程池能够带来三个好处:

  第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。但是要做到合理的利用线程池,必须对其原理了如指掌。

  2. 线程池的使用

  线程池的创建

  我们可以通过ThreadPoolExecutor来创建一个线程池。

  new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler);

  创建一个线程池需要输入几个参数:

  corePoolSize(线程池的基本大小):当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。

  runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。 可以选择以下几个阻塞队列。

  ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。

  LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。

  SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。

  PriorityBlockingQueue:一个具有优先级的无限阻塞队列。

  maximumPoolSize(线程池最大大小):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是如果使用了无界的任务队列这个参数就没什么效果。

  ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字。

  RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略。

  AbortPolicy:直接抛出异常。

  CallerRunsPolicy:只用调用者所在线程来运行任务。

  DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。

  DiscardPolicy:不处理,丢弃掉。

  当然也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。

  keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,并且每个任务执行的时间比较短,可以调大这个时间,提高线程的利用率。

  TimeUnit(线程活动保持时间的单位):可选的单位有天(DAYS),小时(HOURS),分钟(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。

  向线程池提交任务

  我们可以使用execute提交的任务,但是execute方法没有返回值,所以无法判断任务是否被线程池执行成功。通过以下代码可知execute方法输入的任务是一个Runnable类的实例。

  threadsPool.execute(new Runnable() {
  @Override
  public void run() {
  // TODO Auto-generated method stub
  }
  })

  我们也可以使用submit 方法来提交任务,它会返回一个future,那么我们可以通过这个future来判断任务是否执行成功,通过future的get方法来获取返回值,get方法会阻塞住直到任务完成,而使用get(long timeout, TimeUnit unit)方法则会阻塞一段时间后立即返回,这时有可能任务没有执行完。

  通过以上介绍,不知道大家对于线程池是不是有了进一步了解了呢?如果你对于java开发还有什么疑问,或者想进一步学习相关知识的话,可以前来南京学码思java培训机构实地考察,这里开设有专业课程,讲师面授指导教学,一对一为你答疑解惑。你还在犹豫什么?现在咨询在线老师,即可获得直接java教程和学习资料,数量有限,先到先得!

上一篇:Java编程时你需要遵循这几个原则
下一篇:Java和JavaScript有什么区别,学哪个好

相关推荐

免费试听 | 学费咨询 | 在线报名 | 申请补贴 | 软件培训 | 网站地图

2016-2020 南京学码思教育科技有限公司 .All Rights Reserved

苏ICP备16033487号 www.njxms.com.cn

全国热线

400-080-3312

全国监督服务热线:9:00-23:00