Java基础—阻塞队列与线程池

2018-08-04  本文已影响87人  锋Plus

Executor框架用于把任务的提交和执行解耦,任务的提交交给Runnable或者Callable,而Executor框架用来处理任务。Executor框架中最核心的成员就是ThreadPoolExecutor,它是线程池的核心实现类。

在介绍ThreadPoolExecutor前,先要了解下BlockingQueue(阻塞队列)

阻塞队列

两种常见的阻塞场景:

BlockingQueue核心方法

放入数据

获取数据

常见的BlockingQueue

  1. ArrayBlockingQueue:基于数组的阻塞队列实现。生产者放入数据和消费者获取数据,共用同一个锁对象。默认采用非公平锁。
  2. LinkedBlockingQueue:基于链表的阻塞队列。生产者端和消费者端分别采用了独立的锁来控制数据同步,并发性能较好。需要注意的是,LinkedBlockingQueue会默认一个类似无限大小的容量(Integer.MAX_VALUE)。
  3. PriorityBlockingQueue: 基于优先级的阻塞无界队列(优先级的判断通过构造函数传入的Compator对象来决定,但不保证同优先级元素顺序)。不会阻塞数据生产者,而只会在没有可消费的数据时,阻塞数据的消费者。内部控制线程同步的锁采用的是公平锁。
  4. SynchronousQueue:无缓冲的等待队列。每个插入操作必须等待另一个线程的移除操作,同样任何一个移除操作都要等待另一个线程的插入操作。由于队列没有容量,所以不能调用peek操作(返回队列头元素)。
  5. DelayQueue:支持延时获取元素的无界阻塞队列。队列中每个元素必须实现Delayed接口。插入数据的操作(生产者)永远不会被阻塞,只有获取数据的操作(消费者)才会被阻塞。

参考资料:https://www.cnblogs.com/dolphin0520/p/3932906.html


线程池

ThreadPoolExecutor构造方法

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
            ······
                              
    }
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务 
线程池的处理流程

常见的线程池

可重用固定线程的线程池。只有核心线程并且采用无界阻塞队列。

 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

无界线程池,可以进行自动线程回收。无核心线程,采用SynchronousQueue不储存元素的阻塞队列。每次提交任务都会立即有线程去处理,所以适于大量的需要立即处理并且耗时较少的任务。

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

单线程。能确保所有任务在一个线程中按照顺序逐一执行。

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

定时线程池,该线程池可用于周期性地去执行任务,通常用于周期性的同步数据。固定核心线程数,采用DelayedWorkQueue无界队列。

    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

end

参考资料:

《Android进阶之光》
https://www.cnblogs.com/superfj/p/7544971.html


上一篇 下一篇

猜你喜欢

热点阅读