2016-08-09 43 views
1

Ich habe einen Threadpool fester Größe 12. Jetzt habe ich zwei Klassen, die Runnable und 20 Objekte jeder Klasse implementieren. Ich kann alle Aufgaben einreichen und der Threadpool wird seine Aufgabe als regulär erledigen.Einen Threadpool zwischen zwei Klassen teilen

Was ich tun möchte, ist ein Trennzeichen zu machen. Also, falls ich diese 40 Aufgaben einreiche, wird der Thread-Pool nicht mehr als 6 jeder Klasse gleichzeitig verarbeiten. Der Thread-Pool verhält sich also wie 2 kleinerer Thread-Pool der Größe 6. Ist das möglich durch die API von Java oder Guava?

+0

Wäre es eine Option, zwei Pools der Größe 6 zu erstellen? – Fildor

+0

Wenn ich Ihre Frage richtig verstanden habe, denke ich, dass Sie versuchen herauszufinden, wie viele aktive Threads es in einem Threadpool gibt, und begrenzen Sie sie dann, versuchen Sie ['ThreadPoolExecutor.getActiveCount();'] (http://docs.oracle com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html # getActiveCount% 28% 29) – px06

+0

@ px06 Was haben Sie gewonnen, wenn Sie die aktive Anzahl in Bezug auf die Anforderungen in der Frage kennen? – Fildor

Antwort

0

Ohne das "warum" in Frage zu stellen, kann man Semaphore verwenden, die jeweils mit der Zahl 6 erstellt wurden, wobei jeder die Anzahl der Aufgaben jedes Typs auf genau 6 gleichzeitig begrenzt.

Hier ist eine grundlegende Arbeitsprobe:

public class TaskDelimitingTest { 

    private enum Tasks {TASK1, TASK2}; 

    private static ConcurrentHashMap<Tasks, AtomicInteger> taskObserver = new ConcurrentHashMap<>(); 

    public static class Task implements Runnable { 

    private static final Random random = new Random(System.currentTimeMillis()); 

    private final Semaphore sem = new Semaphore(6, true); 
    private final Tasks task; 

    public Task(Tasks task) { 
     this.task = task; 
    } 

    @Override 
    public void run() { 
     try { 
     taskObserver.get(task).incrementAndGet(); 
     Thread.sleep(random.nextInt(1000)); 
     taskObserver.get(task).decrementAndGet(); 
     sem.release(); 
     } catch (InterruptedException e) { 
     e.printStackTrace(); 
     } 
    } 

    public void postToExecution(ExecutorService executor) { 
     try { 
     sem.acquire(); 
     executor.execute(this); 
     } catch (InterruptedException e) { 
     e.printStackTrace(); 
     } 
    } 
    } 

    public static class Task1 extends Task { 

    public Task1() { 
     super(Tasks.TASK1); 
    } 

    } 

    public static class Task2 extends Task { 

    public Task2() { 
     super(Tasks.TASK2); 
    } 

    } 

    public static void main(String[] args) { 
    ExecutorService executor = Executors.newFixedThreadPool(12); 

    Thread t1 = new Thread(() -> { 
     taskObserver.put(Tasks.TASK1, new AtomicInteger()); 
     IntStream.rangeClosed(1, 100).forEach(i -> { 
     new Task1().postToExecution(executor); 
     System.out.println(taskObserver); 
     }); 
    }); 
    Thread t2 = new Thread(() -> { 
     taskObserver.put(Tasks.TASK2, new AtomicInteger()); 
     IntStream.rangeClosed(1, 100).forEach(i -> { 
     new Task2().postToExecution(executor); 
     System.out.println(taskObserver); 
     }); 
    }); 
    t1.start(); 
    t2.start(); 
    } 

} 

In diesem Beispiel I 100 Aufgaben von jedem der beiden Typen in zwei separate Threads zu erstellen, so dass sie miteinander konkurrieren können, habe ich auch eine Thread.sleep in der run Methode, so dass sie unterschiedliche Ausführungszeit simulieren.

Der Ausgang dieses Programms ist - In dem „Warm-up“ -Phase

{TASK2=1, TASK1=1} 
    ... 
    {TASK2=2, TASK1=3} 
    ... 
    {TASK2=4, TASK1=3} 
    ... 
    {TASK2=4, TASK1=4} 
    ... 
    {TASK2=4, TASK1=5} 
    ... 
irgendwann

der Pool gesättigt wird und dann geht es nur so:

{TASK2=6, TASK1=6} 
    ... 

maximal also nur 6 Threads jedes Typs werden gleichzeitig ausgeführt.