2017-07-24 5 views
0

Ich habe einen Beispielcode.ThreadPoolExecutor Java

@Test 
    public void testWithBlockQueue() throws InterruptedException { 
     String poolFormat = "ServiceTaskPool-%d"; 
     int coreSize = 3; 
     int maxSize = 3; 
     int queueSize = 1; 
     int idleThreadLiveInSecond = 35; 

     ThreadFactory factory = new ThreadFactory() { 
      @Override 
      public Thread newThread(Runnable r) { 
       return new Thread(r); 
      } 
     }; 
     ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(queueSize); 
     final ThreadPoolExecutor service = new ThreadPoolExecutor(coreSize, maxSize, idleThreadLiveInSecond, 
       TimeUnit.SECONDS, queue, factory, new ThreadPoolExecutor.AbortPolicy()); 
     service.allowCoreThreadTimeOut(true); 
     passTask(coreSize, service); 
     Thread.sleep(5000); 
     passTask(coreSize, service); 
     System.out.printf("Thread pool state %s", service); 
     Thread.sleep(6000); 
    } 

    protected void passTask(int coreSize, ThreadPoolExecutor service) { 
     for (int i=0; i < coreSize; i++) { 
      service.execute(new Runnable() { 
       @Override 
       public void run() { 
        System.out.printf("Simple printf from %s \n", Thread.currentThread().getName()); 
       } 
      }); 
     } 
    } 

Wenn ich QUEUESIZE Set 2, ich habe Ausnahme, weil ThreadPoolExecutor nicht eine Aufgabe in der Warteschlange einfügen, wenn ich gesetzt QUEUESIZE 3 in Ordnung ist. Ich verstehe nicht warum, wenn ich MaxSize = 4 setze, ist der Test in Ordnung. Es ist von der Dokumentation.

  1. Wenn die Anzahl der Threads ist kleiner als die corePoolSize, erstellen Sie ein neues Thema eine neue Aufgabe auszuführen. Wenn die Anzahl der Threads gleich (oder größer) ist als corePoolSize, setzen Sie die Task in die Warteschlange.
  2. Wenn die Warteschlange voll ist, und die Anzahl der Gewindegänge geringer ist als die MaxPoolSize Erstellen eines neuen Threads in Aufgaben auszuführen.
  3. Wenn die Warteschlange voll ist, und die Anzahl der Gewindegänge größer oder gleich Verwerfen Sie die Aufgabe bis maxPoolSize.

Antwort

0

In der Tat, wenn maxSize = 4, da passTask(coreSize, service)

erster Aufruf geworfen Ausnahme sein könnte, bekommen wir task1, task2, task3. Und thread1, thread2, thread3 werden erstellt, um sie auszuführen.

zum zweiten Mal Anruf passTask(coreSize, service):

  1. i = 0, wir TASK4 bekommen, und TASK4 werden in der Warteschlange gestellt werden.
  2. i = 1, wir bekommen task5.

    2.1. Wenn sich task4 noch in der Warteschlange befindet, wird thread4 erstellt und task5 ausgeführt.

    2.2. Wenn Task4 aus der Warteschlange von Thread1 oder Thread2 oder Thread3 genommen wurde, wird Task5 in die Warteschlange gestellt.

  3. i = 2, whe get Aufgabe6.

    3.1. Wenn sich task4 noch in der Warteschlange befindet, müssen 4 aktive Threads vorhanden sein, und da die Warteschlange voll ist, wird eine Ausnahme ausgelöst.

    3.2. Wenn sich task5 in der Warteschlange befindet, müssen drei Threads am Leben sein, also wird thread4 erstellt und task6 ausgeführt;

    3.3. Wenn die Warteschlange leer ist, wird task6 in die Warteschlange gestellt.

Unter Bedingung 3.1 kann eine Ausnahme ausgelöst werden. Aber in Tests wird die Aufgabe sehr schnell aus der Blockwarteschlange genommen, so dass dies kaum passiert.

P.S.:

Wenn maxSize = 3 und QUEUESIZE = 1, fügen Sie diese Zeile

Thread.sleep(10);

nach

for (int i=0; i < coreSize; i++) {

können Ihren Code laufen ohne Ausnahme machen.

Verwandte Themen