线程池类结构
1.Executor是顶级接口,有一个execute方法。 2.ExecutorService接口提供了管理线程的方法。 3.AbstractExecutorService管理普通线程,SchedulerExecutorService管理定时任务。简单的示例
public class MyThread46 { public static void main(String[] args) { long startTime = System.currentTimeMillis(); final Listl = new LinkedList (); ThreadPoolExecutor tp = new ThreadPoolExecutor(100, 100, 60, TimeUnit.SECONDS, new LinkedBlockingQueue (20000)); final Random random = new Random(); for (int i = 0; i < 20000; i++) { tp.execute(new Runnable() { public void run() { l.add(random.nextInt()); } }); } tp.shutdown(); try { tp.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() - startTime); System.out.println(l.size()); }}
运行结果如下
5219919
ThreadPoolExecutor七个参数
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
1.corePoolSize
线程池当前可以存在的线程数量 2.maximumPoolSize 线程池允许的最大线程数量 3.keepAliveTime 当线程数量比corePoolSize大时才会起作用,终止前的空余线程等待的最长时间。 4.unit keepAliveTime的时间单位 5.workQueue 存储未被执行的任务 6.threadFactory executor创建新线程时使用的工厂 7.handler 当执行被阻塞时使用handlercorePoolSize与maximumPoolSize的关系
1.池中线程数小于corePoolSize,新任务都不排队而是直接添加新线程。
2.池中线程数大于等于corePoolSize,workQueue未满,将新任务加入workQueue而不是添加新线程。 3.池中线程数大于等于corePoolSize,workQueue已满,但是线程数小于maximumPoolSize,添加新的线程来处理被添加的任务。 4.池中线程数大于等于corePoolSize,workQueue已满,并且线程数大于等于maximumPoolSize,新任务被拒绝,使用handler处理被拒绝的任务。Executors
1.newSingleThreadExecutos() 单线程线程池
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), threadFactory)); }
来新任务就排队,workQueue采用了无界队列LinkedBlockingQueue
示例代码如下public class MyThread47{ static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); public static void main(String[] args) { for(int i =0;i<10;i++) { final int index = i; singleThreadExecutor.execute(new Runnable() { @Override public void run() { try { System.out.println(index); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }}
运行结果如下
0123456789
2.newFixedThreadPool(int nThreads) 固定大小线程池
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); }
固定大小线程池和单线程线程池类似,可以手动指定线程数量
示例代码如下public class MyThread48 { public static void main(String[] args) { ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); for (int i = 0; i < 10; i++) { final int index = i; fixedThreadPool.execute(new Runnable() { @Override public void run() { try { System.out.println(index); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }}
运行结果如下
0123456879
3.newCachedThreadPool() 无界线程池
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); }
有多少任务来直接执行,线程池最大数量Integer.MAX_VALUE,60s自动回收空闲线程。
示例代码如下public class MyThread49 { public static void main(String[] args) { ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int index = i; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } cachedThreadPool.execute(new Runnable() { @Override public void run() { System.out.println(index); } }); } }}
运行结果如下
0123456789