java中线程池的使用

线程池的分类

Executor框架的最顶层实现是ThreadPoolExecutor类。
Executors工厂类中提供的:
1、newSingleThreadExecutor
2、newScheduledThreadPool
3、newFixedThreadPool
4、newCachedThreadPool
其实也只是ThreadPoolExecutor的构造函数参数不同而已。
通过传入不同的参数,就可以构造出适用于不同应用场景下的线程池。

corePoolSize: 核心池的大小。 当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中

maximumPoolSize: 线程池最大线程数,它表示在线程池中最多能创建多少个线程;

keepAliveTime: 表示线程没有任务执行时最多保持多久时间会终止。

unit: 参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性

参数分析与execute源码解析
执行任务时,通过下面源代码可以得出以下结论
1、如果线程池中线程数量 < 核心线程数,新建一个线程执行任务;
2、如果线程池中线程数量 >= 核心线程数,则将任务放入任务队列
3、如果线程池中线程数量 >= 核心线程数 且 < maxPoolSize,且任务队列满了,则创建新的线程;
4、如果线程池中线程数量 > 核心线程数,当线程空闲时间超过了keepalive时,则会销毁线程;由此可见线程5、池的队列如果是无界队列,那么设置线程池最大数量是无效的;
6、如果线程池中的任务队列满了,而且线程数达到了maxPoolSize,并且没有空闲的线程可以执行新的任务,这时候再提交任务就会执行拒绝策略

java提供的拒绝策略

AbortPolicy,直接抛出RejectedExecutionException
CallerRunsPolicy,直接在主线程中执行
DiscardOldestPolicy 抛弃队列头的任务,然后重试execute。
DiscardPolicy,直接丢弃

newCachedThreadPool

newCachedThreadPool是一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

package com.enumclass.demo.linepool;

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

/**
 * @ClsaaName: TestNewCashedThreadPOOL
 * @auther: LT
 * @Date: 2019/4/22 11:37
 * @Description: TODO
 * @version:
 */
public class TestNewCashedThreadPOOL {
    public static void main(String[] args) {
        //创建一个可缓存线程池---最大线程数无限大的 也可以做线程服用
        // 无限大小线程池 jvm自动回收
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            newCachedThreadPool.execute(new Runnable() {
                public void run() {
                    //执行任务
                    System.out.println(Thread.currentThread().getName() + "," + temp);

                }
            });
        }


    }
}

运行结果:
在这里插入图片描述
不管你循环多少次,10次就有10个线程来处理,没有进行线程的服用。线程数是无限大的

newFixedThreadPool

newFixedThreadPool是一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
代码演示:

package com.enumclass.demo.linepool;

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

/**
 * @ClsaaName: TestNewCashedThreadPOOL
 * @auther: luotao
 * @Date: 2019/4/22 11:37
 * @Description: TODO
 * @version:
 */
public class TestNewFixedThreadPOOL {
    public static void main(String[] args) {
        //创建一个定长线程池  线程总数量为5,通过这5个线程一直在服用
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            newFixedThreadPool.execute(new Runnable() {
                public void run() {
                    //执行任务
                    System.out.println(Thread.currentThread().getName() + "," + temp);

                }
            });
        }

    }
}

运行结果:
在这里插入图片描述
循环10次,但是线程是5个一直是在复用这5个线程。

newScheduledThreadPool

newScheduledThreadPool是一个定长线程池,支持定时及周期性任务执行。
代码演示:

package com.enumclass.demo.linepool;

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

/**
 * @ClsaaName: TestNewCashedThreadPOOL
 * @auther: luotao
 * @Date: 2019/4/22 11:37
 * @Description: TODO
 * @version:
 */
public class TestNewScheduledThreadPOOL {
    public static void main(String[] args) {
        //创建一个定长线程池
        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            newScheduledThreadPool.schedule(new Runnable() {
                public void run() {
                    //执行任务
                    System.out.println(Thread.currentThread().getName() + "," + temp);

                }
            }, 3, TimeUnit.SECONDS);   //3秒之后执行任务调度
        }


    }
}

运行结果:
在等待3秒后执行,定义的线程数量为3个
在这里插入图片描述

newSingleThreadExecutor

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

package com.enumclass.demo.linepool;

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

/**
 * @ClsaaName: TestNewCashedThreadPOOL
 * @auther: luotao
 * @Date: 2019/4/22 11:37
 * @Description: TODO
 * @version:
 */
public class TestNewSingleThreadExecutor {
    public static void main(String[] args) {
        //创建一个单线程
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            //execute相当于start线程
            newSingleThreadExecutor.execute(new Runnable() {
                public void run() {
                    //执行任务
                    System.out.println(Thread.currentThread().getName() + "," + temp);
                }
            });
        }
        newSingleThreadExecutor.shutdown();



    }
}

执行结果:
在这里插入图片描述
只有一个唯一线程在进行复用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值