spring学习----线程池

线程并发学习

线程并发学习—-核心概念(转载)
线程并发学习—-线程阻塞(sleep、wait、notifyAll、notify、join)
线程并发学习—-线程阻塞(synchronized)
线程并发学习—-线程阻塞(lock)
线程并发学习—-Thread、Runnable、Callable
线程并发学习—-队列(Queue)
spring学习—-线程池
java中一些锁概念整理(转载)

简介

创建和销毁线程需要时间、资源

线程池可以达到这样的效果:一个线程执行完任务之后,继续去执行下一个任务,不被销毁,这样线程利用率提高了。

参数

  • corePoolSize:线程池的大小。线程池创建之后不会立即去创建线程,而是等待线程的到来。当当前执行的线程数大于改值是,线程会加入到缓冲队列;
  • maximumPoolSize:线程池中创建的最大线程数;
  • keepAliveTime:空闲的线程多久时间后被销毁。默认情况下,改值在线程数大于corePoolSize时,对超出corePoolSize值得这些线程起作用。
  • unit:TimeUnit枚举类型的值,代表keepAliveTime时间单位 spring默认使用TimeUnit.SECONDS,不支持配置
   TimeUnit.DAYS; //天
  TimeUnit.HOURS; //小时
  TimeUnit.MINUTES; //分钟
  TimeUnit.SECONDS; //秒
  TimeUnit.MILLISECONDS; //毫秒
  TimeUnit.MICROSECONDS; //微妙
  TimeUnit.NANOSECONDS; //纳秒   
  • workQueue:阻塞队列,用来存储等待执行的任务,决定了线程池的排队策略,spring线程池默认LinkedBlockingQueue,具体使用见createQueue方法
  ArrayBlockingQueue基于数组的先进先出队列,此队列创建时必须指定大小
  LinkedBlockingQueue基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;
  SynchronousQueue这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务
  • threadFactory:线程工厂,是用来创建线程的。默认new Executors.DefaultThreadFactory();
  • handler:线程拒绝策略。当创建的线程超出maximumPoolSize,且缓冲队列已满时,新任务会拒绝
   ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 
  ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
  ThreadPoolExecutor.DiscardOldestPolicy丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
  ThreadPoolExecutor.CallerRunsPolicy://主线程会自己去执行该任务,不会等待线程池中的线程去执行

线程池原理

类图ThreadPoolExecutor

这里写图片描述

继承抽象类 实现ExecutorService接口 实现Executor接口 Executor为顶层接口只定义了一个execute方法

两个执行方法

execute 没有返回值

execute()方法是Executor中声明的方法,在ThreadPoolExecutor有了具体的实现,该方法向线程池提交一个任务,由线程池执行,从源码可以看成改方法没有返回值

submit 有返回值

submit()方法是ExecutorService中声明的方法,在AbstractExecutorService中进行了实现,从源码可以看出该方法底层也是调用execute()方法,并且该方法会返回一个Future

spring配置

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="10" />
        <property name="maxPoolSize" value="50" />
        <property name="keepAliveSeconds" value="180" />
        <property name="queueCapacity" value="80" />
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
        </property>
 </bean>

注:Spring中的线程池是由ThreadPoolTaskExecutor类来实现的。该类的实现原理最终也是调用了java中的ThreadPoolExecutor类中的一些方法,详情见源码

如何合理配置线程池大小

一般需要根据任务的类型来配置线程池大小:
  如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为 NCPU+1
  如果是IO密集型任务,参考值可以设置为2*NCPU
  
个人觉得线程池大小参考并发数配置,具体还是要看具体情况 系统负载、资源利用率

源码

Executor

public interface Executor {
    void execute(Runnable command);
}

public interface ExecutorService extends Executor {
    void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;
   <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

线程池核心类ThreadPoolExecutor

public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6) {
        this(var1, var2, var3, var5, var6, Executors.defaultThreadFactory(), defaultHandler);
    }

    public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6, ThreadFactory var7) {
        this(var1, var2, var3, var5, var6, var7, defaultHandler);
    }

    public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6, RejectedExecutionHandler var7) {
        this(var1, var2, var3, var5, var6, Executors.defaultThreadFactory(), var7);
    }

    public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6, ThreadFactory var7, RejectedExecutionHandler var8) {
        this.ctl = new AtomicInteger(ctlOf(-536870912, 0));
        this.mainLock = new ReentrantLock();
        this.workers = new HashSet();
        this.termination = this.mainLock.newCondition();
        if(var1 >= 0 && var2 > 0 && var2 >= var1 && var3 >= 0L) {
            if(var6 != null && var7 != null && var8 != null) {
                this.corePoolSize = var1;
                this.maximumPoolSize = var2;
                this.workQueue = var6;
                this.keepAliveTime = var5.toNanos(var3);
                this.threadFactory = var7;
                this.handler = var8;
            } else {
                throw new NullPointerException();
            }
        } else {
            throw new IllegalArgumentException();
        }
    }


public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

 private boolean addWorker(Runnable firstTask, boolean core) {
        //省略部分代码
        .....
        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    // Recheck while holding lock.
                    // Back out on ThreadFactory failure or if
                    // shut down before lock acquired.
                    int rs = runStateOf(ctl.get());

                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    //执行Thread的start方法启动线程,执行run方法
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            //创建Thread  默认使用DefalutThreadFactory
            this.thread = getThreadFactory().newThread(this);
        }

Executors

static class DefaultThreadFactory 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;

        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        }
        //创建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;
        }
    }

AbstractExecutorService类

 protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

    /**
     * Returns a {@code RunnableFuture} for the given callable task.
     *
     * @param callable the callable task being wrapped
     * @param <T> the type of the callable's result
     * @return a {@code RunnableFuture} which, when run, will call the
     * underlying callable and which, as a {@code Future}, will yield
     * the callable's result as its result and provide for
     * cancellation of the underlying task
     * @since 1.6
     */
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

spring线程池实现类ThreadPoolTaskExecutor 部分源码,从源码可以看出spring的线程池最终也是通过实现ThreadPoolExecutor 来实现的

public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements AsyncListenableTaskExecutor, SchedulingTaskExecutor {
    private final Object poolSizeMonitor = new Object();
    private int corePoolSize = 1;
    private int maxPoolSize = 2147483647;
    private int keepAliveSeconds = 60;
    private int queueCapacity = 2147483647;
    private boolean allowCoreThreadTimeOut = false;
    private ThreadPoolExecutor threadPoolExecutor;//

 protected ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
        BlockingQueue queue = this.createQueue(this.queueCapacity);
        //初始化ThreadPoolExecutor 
        ThreadPoolExecutor executor = new ThreadPoolExecutor(this.corePoolSize, this.maxPoolSize, (long)this.keepAliveSeconds, TimeUnit.SECONDS, queue, threadFactory, rejectedExecutionHandler);
        if(this.allowCoreThreadTimeOut) {
            executor.allowCoreThreadTimeOut(true);
        }

        this.threadPoolExecutor = executor;
        return executor;
    }
//使用那种队列,默认LinkedBlockingQueue
protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
        return (BlockingQueue)(queueCapacity > 0?new LinkedBlockingQueue(queueCapacity):new SynchronousQueue());
    }    

public ThreadPoolExecutor getThreadPoolExecutor() throws IllegalStateException {
        Assert.state(this.threadPoolExecutor != null, "ThreadPoolTaskExecutor not initialized");
        return this.threadPoolExecutor;
    }
//executor实际就是执行ThreadPoolExecutor的execute方法 
public void execute(Runnable task) {
        ThreadPoolExecutor executor = this.getThreadPoolExecutor();

        try {
            executor.execute(task);
        } catch (RejectedExecutionException var4) {
            throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, var4);
        }
    }

参考文档

https://www.cnblogs.com/lsr-mark/p/7815871.html
https://www.cnblogs.com/dolphin0520/p/3932921.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值