Java:线程池学习(一)

Java:线程池学习()

最近才写完毕业论文的初稿,现在终于有些时间来写一下博客了。

那就来看看线程池的知识点吧。

这篇文章只讲一下常用的一些线程池的构造方法吧。其他方面后面再写写(突然发现以前的博客写的都不太好,以后格式会注意写好一些)。

先来看看我们常用的:

看一下我们平常可能会用得比较多的Executors类中的四个静态方法:

public static ExecutorService newCachedThreadPool()

public static ExecutorService newFixedThreadPool(int nThreads)

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

public static ExecutorService newSingleThreadExecutor()

 

当然,他们都还有另外一个重载的方法,后面再说好伐?

如果你稍微看了一下它们的源码,你会发现到最后他们都会导向下面这个方法中(这个方法在java.util.concurrent.ThreadPoolExecutor中)

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

ThreadPoolExecutor构造函数主要的参数

然后我们来看一下他的主要的属性吧,其实Doug大神已经在注释上写得清楚了,那我就翻译一下吹吹水好了:

corePoolSize核心线程数(后面再讲讲这个)

maximumPoolSize允许创建的最大线程数

keepAliveTime:这个看一下单词也能猜出它的主要作用了吧?当线程池的线程数大于核心线程数的时候,线程空闲时间超过这个时间后还没有任务给它做的话就会关闭。小于等于核心线程数的时候不会被关闭,但是可以通过public void allowCoreThreadTimeOut(true)来设置使其可以被关闭。

TimeUnit unit:keepAliveTime的时间单位(作转换用)

this.keepAliveTime = unit.toNanos(keepAliveTime);

 

BlockingQueue<Runnable> workQueue任务队列

ThreadFactory threadFactory:生成线程的工厂,另一个重载的方法就是带有这个参数的。

RejectedExecutionHandler handler:当线程池满了,但还有新任务提交的时候,就会采用这个策略来进行处理。ThreadPoolExecutor中已经定义好四个实现类了:

public static class AbortPolicy implements RejectedExecutionHandler

直接抛出 RejectedExecutionException 异常,这个是默认的处理策略。

public static class CallerRunsPolicy implements RejectedExecutionHandler

如果线程池没有被关闭,就交由提交任务的线程来执行。

public static class DiscardOldestPolicy implements RejectedExecutionHandler

这个策略就是讲等待队列头的任务给扔掉,然后将这个新任务提交到等待队列中。

public static class DiscardPolicy implements RejectedExecutionHandler

不鸟你,不做任何处理。

 

好了,讲完主要的参数。就来讲一下主要的吧:

newCachedThreadPool

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

上面的你都看完了就知道这里讲什么了。核心线程数为 0,最大线程数为 Integer.MAX_VALUE,keepAliveTime 为 60 秒,任务队列采用 SynchronousQueue。

这种线程池对于任务可以快速地完成的时候会有比较好的性能。如果线程空闲了 60 秒都没有任务,那么将关闭此线程并从线程池中移除。随着所有的线程都会被关闭,整个线程池不会占用任何的系统资源,所以如果线程池空闲了很长时间也不会有问题。

SynchronousQueue 是一个比较特殊的 BlockingQueue,它不储存任何元素,有一个虚拟队列,不管读操作还是写操作,如果当前队列中存储的是与当前操作相同模式的线程,那么当前操作也进入队列中等待;如果是相反模式,则配对成功,从当前队列中取队头节点。

这篇文章暂时不是太深入的聊,或许我会在后续文章中补上聊一下。

 

newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

                                   0L , TimeUnit. MILLISECONDS ,
                                   new LinkedBlockingQueue<Runnable>());
}

核心线程数为 nThreads参数指定的,最大线程数为 nThreadskeepAliveTime 为 0 秒,任务队列采用 LinkedBlockingQueue

LinkedBlockingQueue是基于单向链表实现的阻塞队列。

 

newSingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

核心线程数为 1,最大线程数为 1,keepAliveTime 为 0 秒,任务队列采用 LinkedBlockingQueue

 

newScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue());
}

核心线程数为 corePoolSize参数指定,最大线程数为 Integer.MAX_VALUE,keepAliveTime 为 0 秒,任务队列采用 DelayedWorkQueue。

 

好吧,这篇就先到这里吧。具体的实现流程我后面的博客再详细写一下吧。。。欢迎大佬们点(sao)评(rao)。

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/adrian_dai/article/details/80163965
今日推荐