您的位置:首页 > 新闻频道 > 国内新闻 > 商业资讯>正文

传智播客郑州校区深入解析Java线程精进之线程池进阶

时间:2017-12-22 09:53:03    来源:    浏览次数:    我来说两句() 字号:TT

  今天,传智播客郑州校区来教大家如何玩转线程池。首先,取出来一“条”线程,用完后再扔回去,再取出来,再扔....

  对于Java线程池,传智播客总结了以下特点:

  1.避免大量的创建和销毁带来的性能开销

  2.避免大量的线程间因互相抢占系统资源导致的阻塞现象。

  3.能够对线程进行简单的管理并提供定时执行、间隔执行等功能。

  另外,传智播客还总结了一些关于线程池的缺点,如下:

  1.占用一定的内存空间。

  2.线程越多CPU的调度开销越大。

  3.程序的复杂度会上升。

  其次,传智播客还总结了线程池的基本使用方法

  使用线程池,肯定要对“池”进行配置,像基本的池多大啊,能容纳多少鱼,这些是需要建造前就要确定的.

  • int corePoolSize 核心线程,数

  无论是闲置还是工作中,永远都不会销毁的线程,会一直在线程池中存在,那我们是不是永远都奈何不了它呢,当然不会,把ThreadPoolExecutor的allowCoreThreadTimeOut这个属性设置为true,超过规定时长也会销毁

  • int maximumPoolSize 线程总数,值

  就是我们所有的线程,包括非核心的和上边讲的核心的

  • long keepAliveTime

  如果不是核心线程,超过这个参数的时间就会被干掉

  • TimeUnit unit

  时间总是有单位的,就是上边KeepAliveTime的时间参数.

  类型时枚举,这里举几种常用的,需要时候IDEA会提示

  SECONDS : 秒

  MINUTES : 分

  HOURS : 小时

  DAYS : 天

  • BlockingQueue workQueue

  队列内容较多,我们下边单独讲

  ThreadFactory threadFactory

  这个一般不用,没必要管

  • RejectedExecutionHandler handler

  如果执行的过程中,抛异常了,我们可以用这个来指定,但是系统有默认的,因此这个也可以不用

  使用线程池当然离不开Executor这个接口,具体的实现类在ThreadPoolExecutor中,so我们简单来了解下这个类

  //使用的就是这几个构造,参数我们上边已经讲过了

  public class ThreadPoolExecutor extends AbstractExecutorService {

  .....

  public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueworkQueue);

  public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueworkQueue,ThreadFactory threadFactory);

  public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueworkQueue,RejectedExecutionHandler handler);

  public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueworkQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);

  ...

  }

  接下来,传智播客还为大家整理了常用的几种线程池

  线程都池都是是使用Executors这个类创建出来的

  • CachedThreadPool()

  可缓存线程池:

  线程数无限制

  优先使用空闲线程,如果没有才新建线程

  //创建方式

  ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

  //源码中的定义

  public static ExecutorService newCachedThreadPool() {

  return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

  60L, TimeUnit.SECONDS,

  new SynchronousQueue());

  }

  • FixedThreadPool()

  固定长度的线程池

  可以控制线程的数量

  如果超过则必须排队执行

  //创建方式

  ExecutorService fixedThreadPool = Executors.newFixedThreadPool(线程数量);

  //源码中的定义

  public static ExecutorService newFixedThreadPool(int nThreads) {

  return new ThreadPoolExecutor(nThreads, nThreads,

  0L, TimeUnit.MILLISECONDS,

  new LinkedBlockingQueue());

  }

  • ScheduledThreadPool()

  对,就是它可以定时

  //创建方法

  ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(,线程数);

  //源码中的定义

  public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {

  return new ScheduledThreadPoolExecutor(corePoolSize);

  }

  public ScheduledThreadPoolExecutor(int corePoolSize) {

  super(corePoolSize, Integer.MAX_VALUE,

  DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,

  new DelayedWorkQueue());

  }

  • SingleThreadExecutor()

  所有任务排队执行,一次只能执行一个任务

  //创建方法

  ExecutorService singleThreadPool = Executors.newSingleThreadPool();

  //源码中的定义

  public static ExecutorService newSingleThreadExecutor() {

  return new FinalizableDelegatedExecutorService

  (new ThreadPoolExecutor(1, 1,

  0L, TimeUnit.MILLISECONDS,

  new LinkedBlockingQueue()));

  ,,传智播客为大家简单介绍下队列

  队列类似我们的集合,实现了Collection接口

  队列中排队执行的是我们runnable对象

  常用的队列有如下几种

  • SynchronousQueue:

  有任务来就执行交给空闲线程,如果没有就新建线程执行,so 线程数设置尽可能大即Integer.MAX_VALUE

  • LinkedBlockingQueue:

  永远在核心线程内使用线程,如果超过了核心的线程就在队列中等待执行

  • ArrayBlockingQueue:

  优先使用核心线程数,其次使用非核心的,如果用完了就进入队列等待

  • DelayQueue:

  想进入队列必须实现Delayed接口,达到指定时间后,方可执行任务


注:本文观点仅代表作者本人观点,与本网站无关,本网站亦不对其真实性负责。■

请选择您浏览此新闻时的心情

相关新闻
网友评论
本文共有人参与评论
用户名:
密码:
验证码:  
匿名发表