Java线程池的4种实现

线程池都继承了ExecutorService的接口,所以他们都具有ExecutorService的生命周期方法:运行,关闭,终止;
因为继承了ExecutorService接口,所以它在被创建的时候就是处于运行状态,当线程没有任务执行时,就会进入关闭状态,只有调用了shutdown()的时候才是正式的终止了这个线程池。

1、Java通过Executors工厂类提供我们的线程池一共有4种

ThreadPoolExecutor //指定线程数的线程池。
newFixedThreadPool(); //启动固定线程数的线程池
newCachedThreadPool(); //按需分配的线程池
newScheduledThreadPool(); //定时,定期执行任务的线程池

1.1、ThreadPoolExecutor

ThreadPoolExecutor是线程池的实现类之一,它主要是启动指定数量线程以及将任务添加到队列,并且将任务发送给空闲的线程。
该类构造函数:

public ThreadPoolExecutor(int corePoolSize, //线程的核心线程数。
                              int maximumPoolSize, //线程允许的最大线程数。
                              long keepAliveTime, //当前线程池 线程总数大于核心线程数时,终止多余的空闲线程的时间。
                              TimeUnit unit, //keepAliveTime参数的时间单位
                              BlockingQueue<Runnable> workQueue, //队伍队列,如果线程池达到了核心线程数,并且其他线程都处于活动状态的时候,则将新任务放入此队列。
                              RejectedExecutionHandler handler //拒绝策略,当workQueue队满时,采取的措施。
                              )

1.2、newFixedThreadPool()

在Android中,由于系统资源有限,所以我们最常用的就是fixedThreadPool()。
fixedThreadPool(int size) 就只有一个参数,size,就是线程池中最大可创建多少个线程。
我们来看一下该线程池的实现过程:
线程池newFixedThreadPool()

在实现上跟ThreadPoolExecutor类似fixedThreadPool简化了实现过程,把corePoolSize和maximumpoolSize的值都设为传入的size,并且设置keepAliveTime为0ms,然后采用的是LinkedBlockingQueue队列,这个队列是链式结构,所以是无边界的。可以容纳无数个任务。

总结:比如我创建3个线程的fixedThreadPool ,当3个都为活跃的时候,后面的任务会被加入无边界的链式队列(LinkedBlockingQueue),有空闲,就执行任务。

示例:

private static void fixedThreadPool(int size) 
throws ExecutionException, InterruptedException {
       ExecutorService executorService = Executors.newFixedThreadPool(size);
		//ExecutorService executorService2 = Executors.newSingleThreadExecutor();
       for (int i = 0; i < 10; i++) {
           Future<Integer> task = executorService.submit(new Callable<Integer>() {
               @Override
               public Integer call() throws Exception {
                   System.out.println("执行线程" + Thread.currentThread().getName());
                   return fibc(40);
               }
           });
           System.out.println("第"+i+"次计算,结果:"+task.get());
       }
}

1.3、newCachedThreadPool()

对比fixedThreadPool来说 CachedThreadPool就要更快一些,为什么快呢?
我们来看一下CachedThreadPool的实现源码:

线程池newCachedThreadPool()
可以看到,这里的 maximumPoolSize:线程允许的最大线程数。 为MAX_VALUE(无限大),
也就是说,只要有任务并且其他线程都在活跃态,就会开启一个新的线程 (因为没有上限)
而当有空闲的线程的时候,就会去调用空闲线程执行任务。

示例:

private static void newCacheThreadPool(){
    ExecutorService executorService = Executors.newCachedThreadPool();
    for (int i = 0; i < 100; i++) {
        Future task = executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread()
                .getName()+"---->"+fibc(20));
            }
        });
    }
}

1.4、newScheduledThreadPool()

线程池newScheduledThreadPool()创建ScheduledThreadPoolExecutor很简单,只要传入corePoolSize()线程的核心线程数。就可以开启这个线程池。
然后我们需要使用它的定时任务,就需要实现他的scheduleAtFixedRate方法 这个方法有4个参数:

线程池newScheduledThreadPool()2
第一个参数为要执行的任务。
第二个参数为每次任务执行的延迟,比如传入1,就会每隔1秒执行一次。
第三个参数为执行的周期。
第四个参数为第二个参数的时间单位。

示例:无论实现几个scheduleAtFixedRate方法,他们都互不干扰。

private static void newScheduledThreadPool(){
    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
    executorService.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"----->" + fibc(40));
        }
    },5,3,TimeUnit.SECONDS);

    executorService.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"----->" + fibc(5));
        }
    },1,1,TimeUnit.SECONDS);


    executorService.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"----->" + fibc(1));
        }
    },1,2,TimeUnit.SECONDS);
}

这里实现了3个scheduleAtFixedRate方法,
第一个为5s一次,3个周期执行一次。
第二个为1s一次,1个周期执行一次。
第三个为1s一次,2个周期执行一次。

2.一些方法

ThreadPoolExecutor的shutDown和shutDownNow的区别

线程池 isShutdown和isTerminated的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值