首页 > 编程 > Java > 正文

Java线程池初探

2019-11-08 18:27:11
字体:
来源:转载
供稿:网友

  当我们要有很多子任务需要执行的时候,我们不可能每个子任务开一个线程去执行,这样会严重影响程序的性能,这时候就可以用线程池了。线程池可以重用其中的线程,避免线程反复创建和销毁带来的性能开销,而且可以有效控制并发数。   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实现从网上加载大量图片显示   


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表