Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2、Android线程池相关之队列与池大小的关系 #2

Open
soulrelay opened this issue Aug 14, 2017 · 0 comments
Open

2、Android线程池相关之队列与池大小的关系 #2

soulrelay opened this issue Aug 14, 2017 · 0 comments

Comments

@soulrelay
Copy link
Owner

soulrelay commented Aug 14, 2017

JAVA线程池中队列与池大小的关系

JAVA线程中对于线程池(ThreadPoolExecutor)中队列,池大小,核心线程的关系

  • 1:核心线程:简单来讲就是线程池中能否允许同时并发运行的线程的数量
  • 2:线程池大小:线程池中最多能够容纳的线程的数量。
  • 3:队列:对提交过来的任务的处理模式。

对于线程池与队列的交互有个原则:

如果队列发过来的任务,发现线程池中正在运行的线程的数量小于核心线程,则立即创建新的线程,无需进入队列等待。如果正在运行的线程等于或者大于核心线程,则必须参考提交的任务能否加入队列中去。

1:提交的任务加入队列中

  • 如果提交的任务能加入队列,考虑下队列的值是否有设定,如果没有设定,那么也就是不能创建新的线程,只能在队列中等待,因为理论上队列里面可以容纳无穷大的任务等待。换句话说,此时的线程池中的核心线程数就是池中能否允许的最大线程数。那么池的最大线程数就没有任何意义了。
  • 如果提交的任务能加入队列,队列的值是有限定的,那么首先任务进入队列中去等待,一旦队列中满了,则新增加的任务就进入线程池中创建新的线程。一旦线程池中的最大线程数超过了,那么就会拒绝后面的任务。

2:如果提交的任务不能加入队列

  • 提交的任务不能加入队列,此时就会创建新的线程加入线程池中,一旦超过线程池中最大的数量,则任务被拒绝。

3:队列的三种策略:

  • SynchronousQueue 直接提交,也就是上面讲到的所有任务不进入队列去等待。此时小于核心线程就增加,多于或等于核心线程数时,还是增加线程,最大为线程池中的最大允许。超出就拒绝。
  • LinkedBlockingQueue 无界队列 此时超过核心线程后的任务全部加入队列等待,系统最多只能运行核心线程数量的线程。这种方法相当于控制了并发的线程数量。
  • ArrayBlockingQueue 有界队列 此时超过核心线程后的任务先加入队列等待,超出队列范围后的任务就生成线程,但创建的线程最多不超过线程池的最大允许值。

4:如下源代码:

  • 固定数量的线程池
  public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());
    }

可以看出,这个线程池的核心线程与最大线程为一个值,不等待,超出核心线程一定时间后的线程就被回收掉了。最多同时运行nThreads数量的线程。

  • 单线程池(其实个人认为可以理解为就是核心线程为1的固定线程池)
     public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                        0L, TimeUnit.MILLISECONDS,
                        new LinkedBlockingQueue<Runnable>()));
    }
  • 动态线程池(无界线程池)
 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>());
    }

可以看出,核心线程池为0,线程池的最大是无限,等待时间为60秒,队列为直接提交。
也就是说每次一个任务都直接生成一个线程,线程的无上限,但是一旦线程池中出现了空闲超过60秒的线程则被回收掉。

总的说来,在使用中我们一般使用Executors类的静态方法来创建线程池,除非我们对于线程池非常理解才能自己去灵活的规划线程池类(可以用来继承ThreadPoolExecutor)

@soulrelay soulrelay changed the title Android线程池相关理解 Android线程池相关之队列与池大小的关系 Aug 15, 2017
@soulrelay soulrelay changed the title Android线程池相关之队列与池大小的关系 2、Android线程池相关之队列与池大小的关系 Nov 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant