2012-09-02 23 views
6

Estoy tratando de entender la clase ThreadPoolExecutor. He leído esto answer y el Javadoc. Pero mi experimentación no coincide con la descripción:¿Cómo funciona maximumPoolSize de ThreadPoolExecutor?

Me inicializar el conjunto de subprocesos con una fábrica para el seguimiento de los identificadores de

int tcounter = 0; 
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 1, TimeUnit.MINUTES, 
     new ArrayBlockingQueue<Runnable>(1000), new ThreadFactory() { 

      @Override 
      public Thread newThread(Runnable r) { 
       return new mThread(tcounter++, r); 
      } 
     }); 

public class mThread extends Thread { 
    int id; 

    private mThread(int id, Runnable run) { 
     super(run); 
     GLog.e("created thread " + id); 
     this.id = id; 
    } 

} 

entonces la tarea:

public class mRunanble implements Runnable { 
    int value = 0; 

    private mRunanble(int value) { 
     super(); 
     this.value = value; 
    } 

    @Override 
    public void run() { 
     SystemClock.sleep(3000); 
     Thread t = Thread.currentThread(); 
     if (t instanceof mThread) { 

      GLog.e("Say " + (value) + " on thread " + ((mThread) t).id); 
     } 

    } 

} 

y asignar un botón de la acción :

executor.execute(new mRunanble(i++)); 

Pero spamé ese botón y nunca se creó el tercer subproceso, Entonces, ¿qué es para el segundo parámetro en el constructor ThreadPoolExecutor (maximumPoolSize=4). me specting 4 hilos que se creará y 2 de ellos a matar después de 1 minuto de la final de la ejecución

+0

¿Cuál es 'Runa'? 'mRunanble'? – Jeffrey

+0

Sí, lo siento, ahora está editado – Addev

+0

¿es porque tus hilos están durmiendo? quizás cambiar el ejecutable para hacer una espera ocupada le dará el resultado que espera – happymeal

Respuesta

2

En ThreadPoolExecutor maximumPoolSize viene en la imagen cuando corePoolSize no, no es suficiente para ejecutar sus tareas y si todos no están Ocupado por tareas, entonces solo se está creando una banda de rodadura más para ejecutar la tarea. Esto no puede crecer hasta maxPoolSize.

Editar usted no entendió el concepto de maxPoolsize.please consulte a continuación el enlace.

http://www.bigsoft.co.uk/blog/index.php/2009/11/27/rules-of-a-threadpoolexecutor-pool-size

+0

Pero todos los hilos centrales del OP * están * ocupados por tareas. – Jeffrey

+0

Entonces, cuando envío el botón de spam, se deben crear los 2 hilos adicionales hasta que se cree maximumPoolSize ¿verdad? – Addev

+0

actualizó la respuesta por favor compruebe. – amicngh

4

Desde el API para ThreadPoolExecutor:

Si hay más de corePoolSize pero menos de maximumPoolSize hilos de ejecución, un nuevo hilo sólo se creará si la cola está llena .

Su cola nunca se llena, ya que tiene una capacidad de 1000. Si cambia la capacidad a 1, verá que se está creando Thread s.

La clase Executors usa un SynchronousQueue para sus métodos newCachedThreadPool, por lo que es posible que desee considerar usarlo también.

+0

Si reduzco el valor, recibo java.util.concurrent.RejectedExecutionException – Addev

+1

tan pronto como reduce el número primero, alcanza el límite máximo de la capacidad y luego rechaza las tareas. De esta forma, puede imprimir el tamaño del grupo justo antes de esta excepción que sería igual para maxpoolsize. – amicngh

0

Para hacer ThreadPool crear nuevo hilo adicional (para ampliar el tamaño de la piscina de acuerdo con maximumPoolSize parámetro) tratar de ejecutar este ejemplo sencillo:

public class Main { 

    public static void main(String[] args) throws InterruptedException { 

     ThreadPoolExecutor tpe = new ThreadPoolExecutor(
       1, 2, 500, TimeUnit.MILLISECONDS, 
       new LinkedBlockingQueue<>(1)); 
     System.out.println("init pool size= " + tpe.getPoolSize() + ", queue size=" + tpe.getQueue().size()); 

     tpe.execute(new Task("1st", 10000)); 
     Thread.sleep(1000); 
     print(tpe, "1st"); 

     tpe.execute(new Task("2nd", 0)); 
     Thread.sleep(1000); 
     print(tpe, "2nd"); 

     tpe.execute(new Task("3d", 2000)); 
     Thread.sleep(1000); 
     print(tpe, "3d"); 

     while (tpe.getPoolSize()>1) {   
      Thread.sleep(100); 
     } 
     System.out.println("pool size= " + tpe.getPoolSize() + ", queue size=" + tpe.getQueue().size()); 
     tpe.shutdown(); 
    } 

    private static void print(ThreadPoolExecutor tpe, String name) { 
     System.out.println("After " + name + " execute - pool size= " + tpe.getPoolSize() + ", queue=" + tpe.getQueue()); 
    } 

    private static class Task implements Runnable { 

     private final String name; 
     private final long time; 

     Task(String name, long time) { 
      this.name = name; 
      this.time = time; 
     } 

     @Override 
     public void run() { 
      System.out.println("Run " + Thread.currentThread().getName() + "-" + name); 
      try { 
       Thread.sleep(time); 
      } catch (InterruptedException ex) { 
       Thread.currentThread().interrupt(); 
      } 
      System.out.println("Finish " + Thread.currentThread().getName() + "-" + name); 
     } 

     @Override 
     public String toString() { 
      return name; 
     } 

    } 
} 

que obtendrá la salida que demuestra el impacto de maximumPoolSize y KeepAliveTime:

init pool size= 0, queue size=0 
Run pool-1-thread-1-1st 
After 1st execute - pool size= 1, queue=[] 
After 2nd execute - pool size= 1, queue=[2nd] 
Run pool-1-thread-2-3d 
After 3d execute - pool size= 2, queue=[2nd] 
Finish pool-1-thread-2-3d 
Run pool-1-thread-2-2nd 
Finish pool-1-thread-2-2nd 
pool size= 1, queue size=0 
Finish pool-1-thread-1-1st 
Cuestiones relacionadas