Executors有以下几种方法:
- newFixedThreadPool() 方法:具有固定数量的线程池,线程数量始终不变。当有一个新任务提交时,线程中若有空闲进程变会执行它。若没有,则新的任务会被暂停在一个任务队列中。源码:如下
/** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue. At any point, at most * <tt>nThreads</tt> threads will be active processing tasks. * If additional tasks are submitted when all threads are active, * they will wait in the queue until a thread is available. * If any thread terminates due to a failure during execution * prior to shutdown, a new one will take its place if needed to * execute subsequent tasks. The threads in the pool will exist * until it is explicitly {@link ExecutorService#shutdown shutdown}. * * @param nThreads the number of threads in the pool * @return the newly created thread pool * @throws IllegalArgumentException if {@code nThreads <= 0} */ public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
- newCachedThreadPool() 方法:线程数量不固定,当线程不足时便会产生新的线程。
/** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available, and uses the provided * ThreadFactory to create new threads when needed. * @param threadFactory the factory to use when creating new threads * @return the newly created thread pool * @throws NullPointerException if threadFactory is null */ public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory); }
- newSingleThreadExecutor()方法:只有一个线程的线程池,按先进先出的顺序执行队列中的任务。
/** * Creates a single-threaded executor that can schedule commands * to run after a given delay, or to execute periodically. * (Note however that if this single * thread terminates due to a failure during execution prior to * shutdown, a new one will take its place if needed to execute * subsequent tasks.) Tasks are guaranteed to execute * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent * <tt>newScheduledThreadPool(1)</tt> the returned executor is * guaranteed not to be reconfigurable to use additional threads. * @return the newly created scheduled executor */ public static ScheduledExecutorService newSingleThreadScheduledExecutor() { return new DelegatedScheduledExecutorService (new ScheduledThreadPoolExecutor(1)); }
- newSingleThreadScheduledExecutor() 方法:只有一个线程的线程池,但是可以指定执行时间或执行周期
/** * Creates a single-threaded executor that can schedule commands * to run after a given delay, or to execute periodically. (Note * however that if this single thread terminates due to a failure * during execution prior to shutdown, a new one will take its * place if needed to execute subsequent tasks.) Tasks are * guaranteed to execute sequentially, and no more than one task * will be active at any given time. Unlike the otherwise * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt> * the returned executor is guaranteed not to be reconfigurable to * use additional threads. * @param threadFactory the factory to use when creating new * threads * @return a newly created scheduled executor * @throws NullPointerException if threadFactory is null */ public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) { return new DelegatedScheduledExecutorService (new ScheduledThreadPoolExecutor(1, threadFactory)); }
从他们的源码可以看出,
newCachedThreadPool和newFixedThreadPool最终都是调用的ThreadPoolExecutor方法并且里面的maximumPoolSize、keepAliveTimeunit,workQueue、threadFactory参数都是默认的值。
如果我们直接调用ThreadPoolExecutor方法这些值可以自己定义
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default rejected execution handler.
*
* @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
* @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} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
这是ThreadPoolExecutor源码。
下面我们来写个例子看看效果。
public class MyThreadTest implements Runnable,Comparable<MyThreadTest>{
private static ExecutorService executorService=Executors.newFixedThreadPool(100);
private static Executor myThread=new ThreadPoolExecutor(100,100,0L, TimeUnit.SECONDS,new PriorityBlockingQueue<Runnable>());
private String name;
public MyThreadTest(String name){
this.name=name;
}
public MyThreadTest(){
name="";
}
@Override
public void run(){
try{
Thread.sleep(100);
System.out.println(name+" running....");
}catch(InterruptedException e){
e.printStackTrace();
}
}
@Override
public int compareTo(MyThreadTest o){
int me = Integer.valueOf(name.split("_")[1]);
int other = Integer.valueOf(o.name.split("_")[1]);
return me-other;
}
public static void main(String[] args) {
for (int i=0;i<1000;i++){
// myThread.execute(new MyThreadTest("test_"+(i)));
executorService.execute(new MyThreadTest("test_"+(i)));
}
}
}
test_56 running....
test_39 running....
test_37 running....
test_43 running....
test_57 running....
test_42 running....
test_33 running....
test_15 running....
test_97 running....
test_1 running....
test_74 running....
test_54 running....
。。。
。。。
。。。
test_948 running....
test_943 running....
test_942 running....
test_940 running....
test_941 running....
test_929 running....
test_934 running....
test_932 running....
test_926 running....
test_925 running....
test_923 running....
两者执行效率差不多,如果没有特殊要求建议使用
ExecutorService executorService=Executors.newFixedThreadPool(100);这种方式很简单快捷。如果需要进行其他特殊需求可换成
Executor myThread=new ThreadPoolExecutor(100,100,0L, TimeUnit.SECONDS,new PriorityBlockingQueue<Runnable>());
其中new PriorityBlockingQueue<Runnable>()可以自己定义queue