Java线程池初探

  当我们要有很多子任务需要执行的时候,我们不可能每个子任务开一个线程去执行,这样会严重影响程序的性能,这时候就可以用线程池了。线程池可以重用其中的线程,避免线程反复创建和销毁带来的性能开销,而且可以有效控制并发数。
  Java线程池中的核心类是ThreadPoolExecutor,该类Oracle官网API文档传送门:ThreadPoolExecutor。它有四个构造方法,我们来看下那个参数最多的,其它的也就知道了:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)  

  参数的含义文档里都有,如下(我是从源码里贴过来的,感觉源码里排版更好点。。。):

/**
 * Creates a new {@code ThreadPoolExecutor} with the given initial
 * parameters.
 *
 * @param corePoolSize the number of threads to keep in the pool, even
 *        if they are idle, unless {@code allowCoreThreadTimeOut} is set   
 * @param maximumPoolSize the maximum number of threads to allow in the
 *        pool
 * @param keepAliveTime when the number of threads is greater than
 *        the core, this is the maximum time that excess idle threads
 *        will wait for new tasks before terminating.
 * @param unit the time unit for the {@code keepAliveTime} argument
 * @param workQueue the queue to use for holding tasks before they are
 *        executed.  This queue will hold only the {@code Runnable}
 *        tasks submitted by the {@code execute} method.
 * @param threadFactory the factory to use when the executor
 *        creates a new thread
 * @param handler the handler to use when execution is blocked
 *        because the thread bounds and queue capacities are reached
 * @throws IllegalArgumentException if one of the following holds:<br>
 *         {@code corePoolSize < 0}<br>
 *         {@code keepAliveTime < 0}<br>
 *         {@code maximumPoolSize <= 0}<br>
 *         {@code maximumPoolSize < corePoolSize}
 * @throws NullPointerException if {@code workQueue}
 *         or {@code threadFactory} or {@code handler} is null
 */  

  下面自己结合自己的理解说明下。一般情况下,一个Runnable提交到线程池,如果此时corePoolSize没达到,直接执行,否者放到workQueue(这是个BlockingQueue),如果workQueue满了,则再新建线程执行,如果maximumPoolSize再超了的话,就该handler上了。
  
  Java中有四种我们常用的配置好的线程池,通过Executors中的静态方法,我们可以直接创建它们,下面是源码中它们的配置(当然不只一种new的方法,有重载,具体看源码):

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

  newSingleThreadExecutor和newScheduledThreadPool可以自己去源码中看,ThreadPoolExecutor中参数含义知道,阻塞队列的特性知道的话,应该OK的。
  
  下面是一个简单的使用:

package com.company;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test5 {

    public static void main(String[] args) {

        new Test5().Method();

    }

    public void Method() {

        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i = 0;i < 9;i++) {
            executorService.execute(new MyThread(i));
        }
        executorService.shutdown();

    }

    class MyThread implements Runnable {

        private int mThreadID;

        public MyThread(int mThreadID) {
            this.mThreadID = mThreadID;
        }

        @Override
        public void run() {
            int num = 5;
            while (num > 0) {
                System.out.print(mThreadID + " ");
                num--;
            }
        }

    }

}  

  某次的运行结果:

1 0 2 0 1 0 2 0 1 0 2 2 2 3 1 3 4 3 1 3 4 3 5 4 4 5 5 6 5 4 5 6 8 7 8 6 8 7 8 6 8 7 7 7 6  

  根据结果大体可以看出来最多只允许3个线程同时跑。。。
  
  下面是我在Android中对线程池的一个简单使用:线程池配合RecyclerView实现从网上加载大量图片显示
  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值