【Java线程篇】线程池Executors类几种方法的使用

简介:
线程池的概念类似数据库连接池,为避免系统频繁创建和销毁线程消耗资源,对其进行复用。让一部分线程长时间保持一个激活状态,使用时直接获取一个可用的,而无需新建,不用时还给池中,而无需关闭其。也节约创建和销毁对象的时间。
下面介绍Executor框架处理各种类型的线程池,其扮演了线程工厂的角色。主要有以下的工厂方法。

ExecutorService pool1 = Executors.newFixedThreadPool(0);
ExecutorService pool2= Executors.newSingleThreadExecutor();
ExecutorService pool3 = Executors.newCachedThreadPool();
ScheduledExecutorService pool4= Executors.newSingleThreadScheduledExecutor();
ScheduledExecutorService pool5= Executors.newScheduledThreadPool(0);

1.newFixedThreadPool(int nThreads) ,这个方法返回一个固定数量的线程池,池中的线程数一直保持不变,如果提交的任务用完了池中的所有空闲线程,则新的任务会被暂存哎一个任务队列中,待有线程空闲时,处理在任务队列中等待的任务。
2.newSingleThreadExecutor(),该方法只返回有一个线程的线程池,有多于一个任务被提交到线程池,类似上面的在任务队列中等待,待先承认空闲时执行任务,按先入先出的顺序执行队列中的任务。
3.newCachedThreadPool(),该方法返回一个可根据实际情况调整线程的线程池,池中的线程数不定。当池中的空闲线程都被用尽,此时还有任务被提交,则新建线程处理,任务执行完毕后,将线程返回到线程池等待复用。此方法最小的线程为0,最大为max_value,还有超时时间(超这个时间后空闲线程会被移出,直至0),所以,此方法实际上不存储线程的,只是中转站一样。
newSingleThreadExecutor的jdk源码如下:

 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

4.newSingleThreadScheduledExecutor()方法。此方法返回的是另一个ScheduledExecutorService,返回线程数为1,ScheduledExecutorService在ExecutorService 接口基础上加上了定时任务功能。既在给定时间或周期内执行某个任务。
5.newScheduledThreadPool(X),同上,但可指定指定数量线程。
代码示例(固定数量线程):

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

/**
 * 新建5个固定数量的线程池,提交10个任务,从运行的结果看第一批有5个任务被5个线程处理了,
 * 再间隔一秒后又有5个线程处理了剩下的5个任务,其中从线程的Id可以看出他们是同一批线程。
 * @author T.c
 * 创建时间:2016年12月21日 上午7:36:28
 *
 */
public class FixThreadPool {

    public static class MyTask implements Runnable{
        @Override
        public void run() {
            System.out.println(System.currentTimeMillis()+":Thread ID"+Thread.currentThread().getId());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public static void main(String[] args) {
        MyTask myTask = new MyTask();
        ExecutorService es = Executors.newFixedThreadPool(5); // 创建5个固定数量的线程池
        for(int i=0;i<10;i++){
            es.submit(myTask); // 提交10个任务 此处亦可以用:es.execute(task); 不同之处在于某些场合submit不打印异常的堆栈信息
        }
    }
}

结果如下:

1514000087948:Thread ID10
1514000087948:Thread ID9
1514000087948:Thread ID11
1514000087948:Thread ID13
1514000087949:Thread ID12
1514000088948:Thread ID11
1514000088948:Thread ID9
1514000088948:Thread ID13
1514000088948:Thread ID10
1514000088949:Thread ID12

分析:上述代码中提交了10个任务,池中有5个线程,处理完休息一秒。从结果看前5个和后5个线程Id一样。中间间隔一秒。说明,5个线程先执行了5个人任务,后5个在队列中等待一秒后被同样的5个线程处理了。
其余方法示例可使用类似的方式测试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值