Java并发编程——线程池的使用(一) 简单创建线程池

来源:互联网 发布:机器码加密软件 编辑:程序博客网 时间:2024/05/16 07:10

一、线程池的概念

        线程池,顾名思义就是一个维护了好多线程的“池子”,因为new一个Thread是很消耗资源的,销毁一个线程也是很费资源的,如果能把一些线程维护起来,重复利用(用的时候去线程池里直接去一条闲置的线程),那么将会大大的节约消耗。

       大白话:new Thread()创建线程和销毁线程很费资源,线程池的作用就是维护若干线程,用的时候去线程池里取出线程,该线程完成工作后并不销毁,而是继续维护在线程池中,等待下次的复用。

二、线程池阻塞队列(简单讲解):

         首先,线程池的阻塞队列常用以下几种:LinkedBlockingDeque,LinkedBlockingQueue,SynchronousQueue。

        LinkedBlockingDeque/LinkedBlockingQueue:队列的大小可以决定有多少个正在排队的任务,超过的将会被拒绝。

        SynchronousQueue无队列,超过最大线程数直接拒绝任务。

        说的比较简单,更多详细的讲解可以自行在网上搜搜,因为本篇博客主要讲解线程池,所以这里暂时只知道这些就够用了。

       

三、线程池的简单创建:

        创建简单的线程池有以下几种方法:

ExecutorService service = Executors.newCachedThreadPool();ExecutorService service = Executors.newFixedThreadPool(3);ExecutorService service = Executors.newSingleThreadExecutor();

         其实还有一个:newScheduledThreadPool,这个是延时执行的线程池,可以用来代替Timer定时器,因为篇幅有限,这里先不写了,回头我会单独写一篇博客讲解一下。

Java并发编程——线程池的使用(五)延时执行的线程池ScheduledExecutorService



        下面来说说几种线程池的不同:


3.1 newCachedThreadPool

ExecutorService service = Executors.newCachedThreadPool();

        创建一个可缓存的线程池,理论上县城并没有限制,看下newCachedThreadPool的源码:

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

        标红的文字是指线程最大的数量,取得是整形的最大值,所以在使用这种方式创建线程池的时候,一定要控制好任务的最大数量,否则系统可能会瘫痪。SynchronousQueue的作用会在后面的文子中讲解。

3.2 newFixedThreadPool(num)

ExecutorService service = Executors.newFixedThreadPool(3);

例如这是创建一个维护了三条线程的线程池,当任务数量超过线程池维护的线程数量时,会把任务添加到队列中,依次执行。看下源码:

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

3.3 newSingleThreadExecutor()

ExecutorService service = Executors.newSingleThreadExecutor();
        该方法创建的线程池只有一条线程:
    public static ExecutorService newSingleThreadExecutor() {        return new FinalizableDelegatedExecutorService            (new ThreadPoolExecutor(1, 1,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue<Runnable>()));    }