JAVA多线程之线程池

一、线程池的概念

线程池(Thread Pool)对于限制应用程序中同一时刻运行的线程数很有用。因为每启动一个新线程都会有相应的性能开销,每个线程都需要给栈分配一些内存等等。

我们可以把并发执行的任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程。只要池里有空闲的线程,任务就会分配给一个线程执行。在线程池的内部,任务被插入一个阻塞队列(Blocking Queue ),线程池里的线程会去取这个队列里的任务。当一个新任务插入队列时,一个空闲线程就会成功的从队列中取出任务并且执行它。

具体说来,线程池的出现正是着眼于减少线程池本身带来的开销。线程池采用预创建的技术,在应用程序启动之后,将立即创建一定数量的线程(N1),放入空闲队列中。这些线程都是处于阻塞(Suspended)状态,不消耗CPU,但占用较小的内存空间。当任务到来后,缓冲池选择一个空闲线程,把任务传入此线程中运行。当N1个线程都在处理任务后,缓冲池自动创建一定数量的新线程,用于处理更多的任务。在任务执行完毕后线程也不退出,而是继续保持在池中等待下一次的任务。当系统比较空闲时,大部分线程都一直处于暂停状态,线程池自动销毁一部分线程,回收系统资源。除此之外,线程池能够减少创建的线程个数。通常线程池所允许的并发线程是有上界的,如果同时需要并发的线程数超过上界,那么一部分线程将会等待。

Java 5 在 java.util.concurrent 包中自带了内置的线程池,这里我们只简述一下相关接口和类的使用。

二、常用类和接口



Executor接口:这个接口只包括一个execute方法,是具体Runnable线程任务的执行者

ExecutorService接口

public interface ExecutorService extends Executor 

该接口是一个线程池管理者,继承了Executor类。

这个接口还具有执行Callable任务的能力,通过submit()执行,关于使用Callable和Future开启多线程的方法请参考文章   Java多线程:Callable、Future和FutureTask。该接口的实现类有ThreadPoolExecutor、ScheduledThreadPoolExecutor(具有调度功能)

AbstractExecutorService:ExecutorService执行方法的默认实现
ScheduledExecutorService:一个可定时调度任务的接口 ScheduledThreadPoolExecutor:ScheduledExecutorService的实现,一个可定时调度任务的线程池
 
ThreadPoolExecutor:线程池,可以通过调用Executors以下静态工厂方法来创建线程池并返回一个ExecutorService对象:

关于这个类的一个典型的构造方法如下:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

自定义线程池可以设定核心线程数、最大线程数、等待队列等信息。具体的参数设置不敢妄言,请查阅相关文档

ThreadPoolExecutor具有诸如启动一个线程、返回线程池配置、修改当前线程池配置等方法。

下面的例子,给了一个自定义线程池,并返回了线程池的信息

    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
        CallTask task = new CallTask();
        for (int i = 0; i < 5; i++) {
            threadPoolExecutor.submit(task);
        }
        threadPoolExecutor.setCorePoolSize(10);				            //修改线程池的核心线程数
        System.out.println(threadPoolExecutor.getThreadFactory());	    //返回线程工厂
        System.out.println(threadPoolExecutor.getCorePoolSize());	    //得到当前线程池的核心线程数
        System.out.println(threadPoolExecutor.getPoolSize());		    //得到池中的当前线程数
        System.out.println(threadPoolExecutor.getMaximumPoolSize());    //得到允许的最大线程数
        System.out.println(threadPoolExecutor.getQueue());		        //返回执行程序使用的任务队列
    }

输出结果
java.util.concurrent.Executors$DefaultThreadFactory@12a3a380
10
5
2147483647
[]

Executors类

提供了一系列静态工厂方法用于创建各种线程池,分别是:

newCachedThreadPool //创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool  //创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool  //创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor  //创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

参考文献:java中Executor、ExecutorService、ThreadPoolExecutor介绍


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值