栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

线程池01

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程池01

线程池的创建

线程池的创建可以通过创建ThreadPoolExecutor对象或者调用Executors的工厂方法来创建线程池。但是在阿里巴巴的java开发手册中提到:

[强制]线程池不允许使用Executors去创建,而是通过ThreadPoolExecutors的方式, 这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明: Executors 返回的线程池对象的弊端如下:
1.FixedThreadPool 和SingleThreadPool:
允许的请求队列长度为Integer.MAX _VALUE,可能会堆积大量的请求,从而导致OOM。
2. CachedThreadPool 和ScheduledThreadPool:
允许的创建线程数量为Integer.MAX_VALUE, 可能会创建大量的线程, 从而导致OOM.

ThreadPoolExecutor

因此先看一下怎幺通过创建ThreadPoolExecutor对象来创建一个线程池.
public ThreadPoolExecutorfint corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler

这是ThreadPoolExecutor的构造方法,其中的参数含义如下

    corePoolSize:核心浅程池大小,新的任各到线程池后,线程池会创建新的线程(即使有空困线程) , 直到核心线程池已满。2 maximumPoolSize:最大线程池大小,顾名思义,线程池能创建的线程的最大数目keepAliveTime:线程池的工作线程空闲后,保持存活的吋间TimeUnit:吋间単位BlockingQueue Runnables:用来偖存等待抗行任务的队列threadFactory:线程工厂RejrctedExecutionHandler:当队列和线程池都满了时拒绝任务的策略
重要参数的说明:

corePoolSize和maximumPoolSize
默认情况下线程池中的线程初始时为0,当有新的任务到来时才会创建新线程,当线程数目到达corePoolSize的数量时,新的任务会被缓存到workQueue队列中。如果不断有新的任务到来,队列也满了的话,线程池会再新建线程直到总的线程数目达到maximumPoolSize.如果还有新的任务到来,则要根据RejectedExecutionHandler对新的任务进行相应拒绝处理。

BlockingQueue
一个阻塞队列,用来存储等待执行的任务,常用的有如下几种:

    ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO (先进先出)原则对元素进行排序。
    2 linkedBlockingQueue: 一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue.静态工厂方法Executors.newFixedThreadPool()使用了这个队列。SynchronousQueue: 一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作, 否则插入操作一直处于阻塞状态,吞吐量通常要高于linkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。PriorityBlockingQueue:一个具有优先级的无限阻塞队列

RejectedExecutionHandler
当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。有下面四种JDK提供的策略:

    AbortPolicy,表示无法处理新任务时抛出异常,默认策略CallerRunsPolicy:用调用者所在线程来运行任务。DiscardOldestPolicy:该策略将丢弃最老的一个请求,也就是丢弃即将被执行的任务,并尝试再次提交当前任务。DiscardPolicy: 不处理,丢弃掉
    除了这些JDK提供的策略外,
    还可以自己实现RejectedExecutionHandler接口定义策略。

代码示例

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadTest {
    public static void main(String[] args) {
        //设置核心池大小
        int corePoolSize=5;
        //设置线程池最大能接受多少线程
        int maximumPoolSize=10;
        //设置当前线程数大于corePoolSize,小于maximumPoolSize,超出corePoolSize的线程的线程数的生命周期
        long keepActiveTime=200;
        //设置时间单位
        TimeUnit timeUnit = TimeUnit.SECONDS;
        //设置线程池缓存队列的排队策略为FIFO,并且指定缓存队列大小为5
        BlockingQueueworkQueue=new ArrayBlockingQueue(5);
        //根据前面我们的设置参数,来创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepActiveTime,timeUnit,workQueue);
        for (int i = 1; i <16 ; i++) {
            PoolThread pt = new PoolThread(i);
            executor.execute(pt);
            System.out.println("线程池中的线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+executor.getQueue().size()+",已执行完的任务数目:"+executor.getCompletedTaskCount());
        }
        //使用线程池,一定注意,用完后,要自己关掉线程池
        executor.shutdown();

    }
}
class PoolThread implements Runnable{
    //传入一个任务编号
    private int num;
    public PoolThread(int num) {
        this.num=num;

    }

    @Override
    public void run() {
        System.out.println("任务"+num+"开始执行");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("任务"+num+"执行完毕");

    }
}

注:个人学习总结

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/778277.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号