详解Java四种线程池

线程在并发程序中用的比较多,建立线程原始的有最基本的建立方式:缓存

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //todo
            }
        }).start();
    }复制代码

但若是经过这样创线程那就有点low了:bash

1)每次经过new Thread()建立对象性能不佳。并发

2)线程缺少统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源致使死机或oom。ide

3)缺少更多功能,如定时执行、按期执行、线程中断。性能

这里能够用到Java提供的4种线程池来建立,分别为:spa

  • newCachedThreadPool建立一个可缓存线程池,若是线程池长度超过处理须要,可灵活回收空闲线程,若无可回收,则新建线程。
  • newFixedThreadPool建立一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • newScheduledThreadPool建立一个定长线程池,支持定时及周期性任务执行。
  • newSingleThreadExecutor建立一个单线程化的线程池,它只会用惟一的工做线程来执行任务,保证全部任务按照指定顺序(FIFO,LIFO, 优先级)执行。

下面来比较一下这四种线程池:线程

newCachedThreadPlool:

public static void main(String[] args) {
     ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
     for (int i=0; i<10; i++){
         final int index = i;
         try {
             Thread.sleep(1000);
         } catch (InterruptedException e){

         }
         cacheThreadPool.execute(new Runnable() {
             @Override
             public void run() {
                 System.out.println("第" +index +"个线程" +Thread.currentThread().getName());
             }
         });
     }
 }复制代码

输出结果为:code


能够看出当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用去从新建立线程。cdn

newFixedThreadPool:

public static void main(String[] args) {
    ExecutorService fixedThreadPool =Executors. newFixedThreadPool(3);
    for (int i =1; i<=5;i++){
        final int index=i ;
        fixedThreadPool.execute(new Runnable(){
            @Override
            public void run() {
                try {
                    System.out.println("第" +index + "个线程" +Thread.currentThread().getName());
                    Thread.sleep(1000);
                } catch(InterruptedException e ) {
                    
                }
            }
        });
    }
}复制代码

fixThreadPool会定义开启的线程数,例子中开启了三个,因此结果是前三个线程执行,第4个线程要等待1秒后执行。对象

newScheduledThreadPool:

该线程池能够安排在给定延迟后运行命令或者按期地执行。

延迟执行示例

//corePoolSize - 池中所保存的线程数,即便线程是空闲的也包括在内。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)复制代码

public static void main(String[] args) {
    ScheduledExecutorService scheduledThreadPool= Executors.newScheduledThreadPool(3);
    scheduledThreadPool.schedule(new Runnable(){
        @Override
        public void run() {
            System.out.println("延迟3秒后执行");
        }
    }, 3, TimeUnit.SECONDS);
}复制代码

上述实例会在开启3秒后执行。

按期执行示例

public static void main(String[] args) {
    ScheduledExecutorService scheduledThreadPool= Executors.newScheduledThreadPool(3);
    scheduledThreadPool.scheduleAtFixedRate(new Runnable(){
        @Override
        public void run() {
            System.out.println("延迟3秒后执行");
        }
    }, 1, 3, TimeUnit.SECONDS);  //1:initialDelay, 3:period
}复制代码

上述示例会在开启后延迟1秒执行,而后每3秒执行一次。

newSingleThreadExecutor:

public static void main(String[] args) {
    ExecutorService singleThreadPool= Executors.newSingleThreadExecutor();
    for(int i=1;i<=5;i++){
        int index=i;
        singleThreadPool.execute(new Runnable(){
            @Override
            public void run() {
                try{
                    System.out.println("第"+index+"个线程");
                    Thread.sleep(2000);
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }
            } });
    }
}复制代码


会每2秒创一个线程,并且是顺序的执行各个任务,而且在任意给定的时间不会有多个线程是活动的,其实与newFixedThreadPool(1)效果是同样的。

相关文章
相关标签/搜索