美文网首页
【线程池】

【线程池】

作者: hello高world | 来源:发表于2018-03-25 22:52 被阅读0次

    1、Executor接口

    只有一个方法,void execute(Runnable command);

    2、ExecutorService

    因为Exectuor没有管理线程执行的状态管理,所以就创建了他。你可以用他来关闭、查看状态、执行。还提供了Callable参数
    <T> Future<T> submit(Callable<T> task);

    3、Runnable和Callable

    Callable可以返回参数、检查异常的检查,而Runnable不行

    4、线程池类型

    • 单线程池
    public static ExecutorService   
       newSingleThreadExecutor(ThreadFactory threadFactory) {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>(),
                                        threadFactory));
    }
    
    • 固定大小线程池
        public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }
    
    • 无界线程池(最大Integer.MAX_VALUE)
     public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
    
    • 固定大小+定时线程池
       public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
            return new ScheduledThreadPoolExecutor(corePoolSize);
        }
    

    5、线程池队列

    • 有界队列
      可以自行配置new LinkedBlockingQueue<Runnable>(大小限制)

    • 无界队列
      1、单线程池
      2、固定大小线程池
      分别使用了LinkedBlockingQueue作为队列,默认构造函数队列大小是Integer.MAX_VALUE,也就是无界。

    6、线程池运作方式

    • 以最小线程值corePoolSize来运行任务,待队列满了,才创建一个新线程从队列中接收新任务。一直到最大线程值大小maximumPoolSize

    所以我们可以看出来,单线程池和固定线程池,两个值一样的。这样就避免了上面的情况。

    但是对于无界线程池:
    corePoolSize=0,
    maximumPoolSize=Integer.MAX_VALUE。
    如果等待队列满了,在运行,势必是有问题的,所以他使用了同步移交SynchronousQueue。这个isEmpty()方法一直是true,这样ThreadPoolExecutor就会跟其他的不一样,直接有一个任务就执行一个。

    7、拒绝策略

    队列满了怎么办?

    • 最早进入等待的任务出局
    • 想进入的任务出局
    • 想进入的任务退回给客户端

    其实这个是流控,可以使用信号量或者RateLimter来做控制

    8、特性

    • 默认的都是非守护线程,这样你必须关闭,否则系统不会退出
    • 线程池在同构线程时候性能最好,如果有异构线程,可能会出现某些任务延迟很久。
    • 线程中的任务尽量不要有依赖,否则可能会出现饥饿线程。A线程等待B任务,B任务等待A任务。如果只有使用单线程池,这样就锁住了。

    相关文章

      网友评论

          本文标题:【线程池】

          本文链接:https://www.haomeiwen.com/subject/aklbrxtx.html