java自定义线程池

java自定义线程池

    • 阿里java开发手册
    • 定义线程池
    • 使用线程池
    • 线程工厂
    • 几种常用队列
    • 线程池拒绝策略

阿里java开发手册

第3条规定:线程资源必须通过线程池提供,不允许在应用中自行显式创建线程

第4条规定:线程池不允许使用Executors创建,而是通过ThreadPoolExecutor的方式创建,这样的处理方式能让编写代码的攻城狮更加明确线程池的运行规则,规避资源耗尽(OOM)的风险

定义线程池

java线程池的使用其实很简单,直接new java.util.concurrent.ThreadPoolExecutor(),这里选择构造参数最多的介绍一下各个入参含义:
java自定义线程池_第1张图片

       //定义线程池
       //线程池的基本大小,就是维持线程数
        int corePoolSize = 10;
        //线程池的最大值
        int maximumPoolSize =50;
        //超过多长时间对超过基本线程的空闲线程回收
        long keepAliveTime = 100L;
        //指上面指定时间的单位
        TimeUnit unit = TimeUnit.SECONDS;
        //线程等待队列,简单定义等待长度
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
        //线程工厂,默认实现
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        //线程池的拒绝策略,默认实现
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );

使用线程池

使用就是直接调用execute()方法, 入参为定义的线程,java自定义线程池_第2张图片

  threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("这是一个测试线程");
            }
        });

线程工厂

当然我们可以自定义线程工厂,大部分作用就提供线程命名,方便排查问题,自定义的话就直接向java默认实现类抄作业就行

java自定义线程池_第3张图片

自定义线程工厂:

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class MyThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    MyThreadFactory(String name) {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
        if (null == name || name.isEmpty()) {
            name = "pool";
        }
        namePrefix = name + "-thread-";
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}

几种常用队列

1.ArrayBlockingQueue:规定大小的BlockingQueue,其构造必须指定大小。其所含的对象是FIFO顺序排序的。

2.LinkedBlockingQueue:大小不固定的BlockingQueue,若其构造时指定大小,生成的BlockingQueue有大小限制,不指定大小,其大小有Integer.MAX_VALUE来决定。其所含的对象是FIFO顺序排序的。

3.PriorityBlockingQueue:类似于LinkedBlockingQueue,但是其所含对象的排序不是FIFO,而是依据对象的自然顺序或者构造函数的Comparator决定。

4.SynchronizedQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成。

线程池拒绝策略

内置了四种拒绝策略,按需求选择:
1.ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

2.ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。

3.ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务

4.ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

你可能感兴趣的:(java,java,多线程,线程池)