Executors创建的4种线程池的使用

原创
2018/09/30 19:19
阅读数 9.3W

Java通过Executors提供四种线程池,分别为:

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

线程代码:

package org.morecare.thread;

public class ThreadForpools implements Runnable{

    private Integer index;
    public  ThreadForpools(Integer index)
    {
        this.index=index;
    }
    @Override
    public void run() {
        /***
         * 业务......省略
         */
        try {
            System.out.println("开始处理线程!!!");
            Thread.sleep(index*100);
            System.out.println("我的线程标识是:"+this.toString());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

(1) newCachedThreadPool


创建一个可缓存线程池,应用中存在的线程数可以无限大

package org.morecare.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NewCachedThreadPool {

    /**
     * 我们获取四次次线程,观察4个线程地址
     * @param args
     */
    public static  void main(String[]args)
    {
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        System.out.println("****************************newCachedThreadPool*******************************");
        for(int i=0;i<4;i++)
        {
            final int index=i;
            newCachedThreadPool.execute(new ThreadForpools(index));

        }
    }
}

输出结果是:可以有无限大的线程数进来(线程地址不一样),但需要注意机器的性能,需要线程太多,会导致服务器出现问题。

(2) newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:

package org.morecare.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NewFixedThreadPool {
    /**
     * 我们获取四次次线程,观察4个线程地址
     * @param args
     */
    public static  void main(String[]args)
    {
        //线程池允许同时存在两个线程
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(2);
        System.out.println("****************************newFixedThreadPool*******************************");
        for(int i=0;i<4;i++)
        {
            final int index=i;
            newFixedThreadPool.execute(new ThreadForpools(index));
        }
    }
}

Executors.newFixedThreadPool(2);在线程池中保持二个线程可以同时执行,但是注意,并不是说线程池中永远都是这二个线程,只是说可以同时存在的线程数,当某个线程执行结束后,会有新的线程进来

输出结果:每次只有两个线程在处理,当第一个线程执行完毕后,新的线程进来开始处理(线程地址不一样)

(3)  newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:

package org.morecare.thread;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class NewScheduledThreadPool {
    /**
     * 我们获取四次次线程,观察4个线程地址
     * @param args
     */
    public static  void main(String[]args)
    {
        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(2);
        System.out.println("****************************newFixedThreadPool*******************************");
        for(int i=0;i<4;i++)
        {
            final int index=i;
            //延迟三秒执行
            newScheduledThreadPool.schedule(new ThreadForpools(index),3, TimeUnit.SECONDS);
        }
    }
}

执行结果:延迟三秒之后执行,除了延迟执行之外和newFixedThreadPool基本相同,可以用来执行定时任务

newScheduledThreadPool共计有三个方法:

    schedule(commod,delay,unit) ,这个方法是说系统启动后,需要等待多久执行,delay是等待时间。只执行一次,没有周期性。

    scheduleAtFixedRate(commod,initialDelay,period,unit),这个是以period为固定周期时间,按照一定频率来重复执行任务,initialDelay是说系统启动后,需要等待多久才开始执行。例如:如果设置了period为5秒,线程启动之后执行了大于5秒,线程结束之后,立即启动线程的下一次,如果线程启动之后只执行了3秒就结束了那执行下一次,需要等待2秒再执行。这个是优先保证任务执行的频率,

    scheduleWithFixedDelay(commod,initialDelay,delay,unit),这个是以delay为固定延迟时间,按照一定的等待时间来执行任务,initialDelay意义与上面的相同。例如:设置了delay为5秒,线程启动之后不管执行了多久,结束之后都需要先生5秒,才能执行下一次。这个是优先保证任务执行的间隔

4) newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:

package org.morecare.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NewSingleThreadExecutor {
    /**
     * 我们获取四次次线程,观察4个线程地址
     * @param args
     */
    public static  void main(String[]args)
    {
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        System.out.println("****************************newFixedThreadPool*******************************");
        for(int i=0;i<4;i++)
        {
            final int index=i;
            newSingleThreadExecutor.execute(new ThreadForpools(index));

        }
    }
}

展开阅读全文
加载中
点击加入讨论🔥(1) 发布并加入讨论🔥
打赏
1 评论
26 收藏
3
分享
返回顶部
顶部