总结线程池的使用方式
Java 通过 Executors 提供四种线程池, 分别为:
newCachedThreadPool 创建一个可缓存线程池, 如果线程池长度超过处理需要, 可灵活回收空闲线程, 若无可回收, 则新建线程.
newFixedThreadPool 创建一个定长线程池, 可控制线程最大并发数, 超出的线程会在队列中等待.
newScheduledThreadPool 创建一个定长线程池, 支持定时及周期性任务执行.
newSingleThreadExecutor 创建一个单线程化的线程池, 它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序 (FIFO, LIFO, 优先级) 执行.
线程池比较单线程的优势在于:
重用存在的线程, 减少对象创建、消亡的开销, 性能佳.
可有效控制最大并发线程数, 提高系统资源的使用率, 同时避免过多资源竞争, 避免堵塞.
提供定时执行、定期执行、单线程、并发数控制等功能.
newCachedThreadPool
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public static void main (String[] args) { ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); for (int i = 0 ; i < 10 ; i++) { final int index = i; try { Thread.sleep(10 ); } catch (InterruptedException e) { e.printStackTrace(); } cachedThreadPool.execute(new Runnable () { public void run () { System.out.println(index); } }); } }
1 2 3 4 5 public static ExecutorService newCachedThreadPool () { return new ThreadPoolExecutor (0 , Integer.MAX_VALUE, 60L , TimeUnit.SECONDS, new SynchronousQueue <Runnable>()); }
创建一个可缓存线程池, 如果线程池长度超过处理需要, 可灵活回收空闲线程, 若无可回收, 则新建线程.
这里的线程池是无限大的, 当一个线程完成任务之后, 这个线程可以接下来完成将要分配的任务, 而不是创建一个新的线程,
java api 1.7 will reuse previously constructed threads when they are available.
newFixedThreadPool
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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 () { public void run () { try { System.out.println(index); Thread.sleep(10 ); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }
1 2 3 4 5 public static ExecutorService newFixedThreadPool (int nThreads) { return new ThreadPoolExecutor (nThreads, nThreads, 0L , TimeUnit.MILLISECONDS, new LinkedBlockingQueue <Runnable>()); }
创建一个定长线程池, 可控制线程最大并发数, 超出的线程会在队列中等待
定长线程池的大小最好根据系统资源进行设置. 如 Runtime.getRuntime().availableProcessors()
1 2 3 4 5 6 7 8 9 10 public static void main (String[] args) { ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5 ); for (int i = 0 ; i < 10 ; i++) { scheduledThreadPool.schedule(new Runnable () { public void run () { System.out.println("delay 3 seconds" ); } }, 3 , TimeUnit.SECONDS); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static ScheduledExecutorService newScheduledThreadPool (int corePoolSize) { return new ScheduledThreadPoolExecutor (corePoolSize); } public ScheduledThreadPoolExecutor (int corePoolSize) { super (corePoolSize, Integer.MAX_VALUE, 0 , NANOSECONDS, new DelayedWorkQueue ()); } public ThreadPoolExecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this (corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
newSingleThreadExecutor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public static void main (String[] args) { ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); for (int i = 0 ; i < 10 ; i++) { final int index = i; singleThreadExecutor.execute(new Runnable () { public void run () { try { System.out.println(index); Thread.sleep(2000 ); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }
1 2 3 4 5 6 public static ExecutorService newSingleThreadExecutor () { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor (1 , 1 , 0L , TimeUnit.MILLISECONDS, new LinkedBlockingQueue <Runnable>())); }
按顺序来执行线程任务 但是不同于单线程, 这个线程池只是只能存在一个线程, 这个线程死后另外一个线程会补上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 public class ThreadPoolExecutorTest { public static void main (String[] args) { int corePoolSize = 5 ; long keepActiveTime = 200 ; TimeUnit timeUnit = TimeUnit.SECONDS; BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue <Runnable>(5 ); ThreadPoolExecutor executor = new ThreadPoolExecutor (corePoolSize, maximumPoolSize, keepActiveTime, timeUnit,workQueue); for (int i = 0 ; i < 15 ; i++) { MyTask myTask = new MyTask (i); executor.execute(myTask); System.out.println("线程池中线程数目: " +executor.getPoolSize() + ", 队列中等待执行的任务数目: " +executor.getQueue().size() + ", 已执行完的任务数目: " +executor.getCompletedTaskCount()); } executor.shutdown(); } } class MyTask implements Runnable { private int num; public MyTask (int num) { this .num = num; } @Override public void run () { System.out.println("正在执行task " + num ); try { Thread.currentThread().sleep(5000 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("task " + num + "执行完毕" ); } public long getDelta () throws ParseException { long t1 = new Date ().getTime(); String str = "2016-11-11 15:15:15" ; SimpleDateFormat simpleDateFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ); long t2 = simpleDateFormat.parse(str).getTime(); return t2 - t1; } }