2016-03-30 14 views
2

Vielleicht ist es einfach zu tun, aber ich weiß nicht, wie.abrufen Thread Kontext Java

Zuerst habe ich Klasse A, die eine oder mehrere Klasse B (Runnable) mit einem Executor erstellt. Jede Klasse B muss einige Aufgaben erledigen, aber ich möchte wissen, wann jeder Thread beendet ist.

Class A { 
    private ScheduledExecutorService scheduler; 
    private int nbThread=3; 
    public A(){ 
     scheduler = Executors.newScheduledThreadPool(nbThread); 
    } 

    public start(){ 
     for (int i = 0; i < nbThread; i++) { 
      scheduler.execute(new B(); 
     } 
    } 

}

Class B implement Runnable { 

    public B(){ 

    } 

    @Override 
    public void run(){ 
     System.out.printl("test"); 
    } 

}

Nun, was ich will, ist nur andere Aufgaben zu tun, wenn diese drei Fäden jeden (System.out.println ("test") drucken Wenn Thread Nr. 1 endet nicht, dann tun wir alles. Ich bin nicht sehr stark in Java, also brauche ich etwas Hilfe. danke

+0

haben Sie versucht, aus [schließt sich?] (Https://docs.oracle.com/javase/tutorial/essential/concurrency/join. html) –

+0

nein, du denkst es ist eine gute lösung? ich schaue nach Future, irgendeine idee? danke – Caroline

Antwort

3

Was Sie wollen zu sehen ist Future Schnittstelle in Java-Concurrent-Paket.

Ich aktualisierte Ihre start Methode, um Ihnen ein Beispiel zu geben, wie man es benutzt.

public void start() { 
    Future<?>[] futures = new Future[nbThread]; 

    for (int i = 0; i < nbThread; i++) { 
     futures[i] = scheduler.submit(new B()); 
    } 

    for (int i = 0; i < nbThread; i++) { 
     try { 
      futures[i].get(); // waits until the current B is done, and then just returns null 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    // All futures now finished executing 
} 

Update: Eine alternative Lösung, wenn man immer warten wollen, bis alle Aufgaben erledigt sind, ist ExecutorService.invokeAll zu verwenden. Wie im folgenden Beispiel (beachten Sie, dass ich BCallable umzusetzen geändert.

class A { 
    private ScheduledExecutorService scheduler; 
    private int nbThread = 3; 

    public A() { 
     scheduler = Executors.newScheduledThreadPool(nbThread); 
    } 

    public void start() { 
     List<Callable<Object>> callables = new ArrayList<>(); 
     callables.add(new B()); 
     callables.add(new B()); 
     callables.add(new B()); 
     try { 
      scheduler.invokeAll(callables); // blocks until all B finished executing 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     // All B's now finished executing 

    } 
} 

class B implements Callable<Object> { 

    public B() { 

    } 

    @Override 
    public Object call() throws Exception { 
     System.out.println("test"); 
     return null; 
    } 
} 
+0

danke gustf, ich werde jetzt testen :) – Caroline

+0

also frage ich: wie zu wissen, dass jede futur ausgeführt wird ? Wenn ich eine andere Methode executeTeskAfterAllThread() habe, wie kann man wissen, ob alle laufenden Threads ausgeführt werden? – Caroline

+0

future.get() wartet, bis die Zukunft ausgeführt wird. Daher wartet jede Iteration in der letzten Schleife darauf, dass der aktuelle B die Ausführung beendet. das bedeutet, dass nach der Schleife (Kommentar hinzugefügt) alle Futures – gustf