线程池参数详解

线程池7大参数

  • corePoolSize
  • maximumPoolSize
  • keepAliveTime
  • unit
  • workQueue
  • threadFactory
  • handler

corePoolSize:核心线程数。也可以设置超时,allowCoreThreadTimeOut参数来控制,可以使用allowCoreThreadTimeOut(true)方法设置

maximumPoolSize:最大线程数,包含核心线程数。

keepAliveTime: 除了核心线程数的超时时间(如果allowCoreThreadTimeOut为false)。

unit:超时时间的单位。

workQueue:阻塞队列。

threadFactory:线程工厂。

handler:拒绝策略。

线程执行流程

  1. 首先判断有没有线程,没有线程先创建线程,数量直到核心线程数。
  2. 如果已经达到核心线程数,进入阻塞队列。
  3. 如果阻塞队列达到最大数量,则创建新的线程,直到线程池达到最大线程数。
  4. 如果超了最大线程数,则执行拒绝策略。
  5. 当线程(非核心)的闲置时间超过了超时时间,则被回收,如果核心线程也设置了超时,也会被回收。

阻塞队列

种类

  • LinkedBlockingQueue: 基于链表实现,默认长度为Integer.MAX_VALUE
    。如果设置了这个参数,maximumPoolSize这个参数就没什么意义了。
  • ArrayBlockingQueue:基于数组实现,长度可以自定义。
  • PriorityBlockingQueue:优先级的阻塞队列,可以通过自定义比较器来控制优先级,这里只是弹出任务的优先级,具体能不能先执行,还得看cpu。
  • DelayQueue:延迟队列,可以通过getDelay设置延迟时间。
  • SynchronousQueue: 同步阻塞队列。

实例

        PriorityBlockingQueue(线程池放一个 可以看出优先级)

public class ThreadTestUtil {

    public static void main(String[] args) {
        
        BlockingQueue blockingQueue = new PriorityBlockingQueue<TestTask>(5,(o1,o2)->{
            return o1.getPriority()-o2.getPriority();
        });
        NamedThreadFactory namedThreadFactory = new NamedThreadFactory("xiaoyi-->",false);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 3, TimeUnit.MINUTES, blockingQueue,
                namedThreadFactory, new ThreadPoolExecutor.DiscardPolicy());

        for (int i = 0; i < 10; i++) {
            final int s = i;
            threadPoolExecutor.execute(new TestTask(s));
        }
    }
}
@Data
class TestTask implements Comparable,Runnable{

    private int priority;

    TestTask(int priority){
        this.priority = priority;
    }

    @Override
    public int compareTo(@NotNull Object o) {
        return priority;
    }

    @Override
    public void run() {
        System.out.println("shu-->"+priority);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

DelayQueue延迟队列


public class ThreadTestUtil {

    public static void main(String[] args) {

        DelayQueue delayQueue = new DelayQueue<DelayedElement>();
        NamedThreadFactory namedThreadFactory = new NamedThreadFactory("xiaoyi-->",false);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 3, TimeUnit.MINUTES, delayQueue,
                namedThreadFactory, new ThreadPoolExecutor.DiscardPolicy());

        for (int i = 0; i < 10; i++) {
            final int s = i;
            DelayedElement delayedElement = new DelayedElement(3000, s);
            threadPoolExecutor.execute(delayedElement);
        }
    }
}
public class DelayedElement implements Delayed,Runnable {

    /**
     * 延迟时间
     */
    private long delay;
    /**
     * 过期时间
     */
    private long expire;

    /**
     * 优先级
     */
    private int priority;

    public DelayedElement(long delay, int priority) {
        this.delay = delay;
        this.priority = priority;
        expire = System.currentTimeMillis() + delay;
    }

    /**
     * 需要实现的接口,获得延迟时间   用过期时间-当前时间
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(this.expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    /**
     * 用于延迟队列内部比较排序
     */
    @Override
    public int compareTo(Delayed o) {
        DelayedElement delayedElement = (DelayedElement) o;
        return this.priority - ((DelayedElement) o).getPriority();
    }

    public int getPriority() {
        return priority;
    }

    @Override
    public void run() {
        System.out.println("Kaishi--->"+priority);
    }
}

SynchronousQueue同步阻塞队列

public class ThreadTestUtil {

    public static void main(String[] args) {
        SynchronousQueue syncQueue = new SynchronousQueue();
        NamedThreadFactory namedThreadFactory = new NamedThreadFactory("xiaoyi-->",false);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, 5, 3, TimeUnit.MINUTES, syncQueue,
                namedThreadFactory, new ThreadPoolExecutor.DiscardPolicy());
        threadPoolExecutor.execute(new PutTask(syncQueue));
        threadPoolExecutor.execute(new TakeTask(syncQueue));
    }
}

/**
 * 放数据
 */
class PutTask implements Runnable {
    BlockingQueue synchronousQueue;

    PutTask(BlockingQueue synchronousQueue) {
        this.synchronousQueue = synchronousQueue;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 11; i++) {
                System.out.println("放入的数字:"+i );
                synchronousQueue.put(i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 拿数据
 */
class TakeTask implements Runnable {
    BlockingQueue synchronousQueue;

    TakeTask(BlockingQueue synchronousQueue) {
        this.synchronousQueue = synchronousQueue;
    }

    @Override
    public void run() {
        try {
            while (true){
                System.out.println(Thread.currentThread().getName() + " take " + synchronousQueue.take());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

四种常见的线程池

  • newFixedThreadPool (固定线程池的线程数,队列是LinkedBlockingQueue)
  • newCachedThreadPool (有超时时间,队列是SynchronousQueue)
  • newSingleThreadExecutor (单线程的线程池,最大和核心线程数为1)
  • newScheduledThreadPool (定时线程池,队列是DelayQueue)

拒绝策略

  • ThreadPoolExecutor.AbortPolicy:抛出异常,丢弃任务,阻止系统正常工作。
  • ThreadPoolExecutor.DiscardPolicy: 直接丢弃最新任务,但不抛出异常
  • ThreadPoolExecutor.DiscardOldestPolicy: 丢弃最老的任务,然后重新尝试执行新任务
  • ThreadPoolExecutor.CallerRunsPolicy: 只要线程池未关闭,直接调用线程池的线程执行该任务。

线程池的状态

  • RUNNING: 运行的状态
  • SHUTDOWN: 不接受新任务,但会继续处理队列的任务
  • STOP: 不接受新任务,不会处理队列的任务,中断正在执行的任务
  • TIDYING: 当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。 
  • TERMINATED: 线程池彻底终止
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值