2016-04-06 22 views
3

In diesem Projekt führt eine Manager Ereigniswarteschlange aus, und um das Ergebnis des Ereignisses zurückzugeben, wird ein Rückruf verwendet (der Rückruf erweitert sich nicht). Der Manager läuft in einem separaten Thread und versendet die Ereignisse. Sobald die Ereignisse enden, ruft derselbe Thread die Rückrufe auf. Das bedeutet, dass das nächste Ereignis nicht ausgelöst wird, bevor der Rückruf des vorherigen Ereignisses beendet wird. Um dies zu vermeiden, habe ich mir vorgenommen, dass der Manager für jeden Callback einen neuen Thread erstellt und die Callbacks dort ausführt. Wie gut ist diese Lösung in Bezug auf Design-Praktiken, und gibt es einen besseren Weg, dies zu erreichen?Java-Callback für einen neuen Thread ausführen

Antwort

5

Ein einfacher Callback Code:

import java.util.concurrent.*; 
import java.util.*; 

public class CallBackDemo{ 
    public CallBackDemo(){ 
     System.out.println("creating service"); 
     ExecutorService service = Executors.newFixedThreadPool(10); 

     try{ 
      for (int i=0; i<10; i++){ 
       Callback callback = new Callback(i+1); 
       MyCallable myCallable = new MyCallable((long)i+1,callback); 
       Future<Long> future = service.submit(myCallable); 
       //System.out.println("future status:"+future.get()+":"+future.isDone()); 
      } 
     }catch(Exception err){ 
      err.printStackTrace(); 
     } 
     service.shutdown(); 
    } 
    public static void main(String args[]){ 
     CallBackDemo demo = new CallBackDemo(); 
    } 
} 
class MyCallable implements Callable<Long>{ 
    Long id = 0L; 
    Callback callback; 
    public MyCallable(Long val,Callback obj){ 
     this.id = val; 
     this.callback = obj; 
    } 
    public Long call(){ 
     //Add your business logic 
     System.out.println("Callable:"+id+":"+Thread.currentThread().getName()); 
     callback.callbackMethod(); 
     return id; 
    } 
} 
class Callback { 
    private int i; 
    public Callback(int i){ 
     this.i = i; 
    } 
    public void callbackMethod(){ 
     System.out.println("Call back:"+i); 
     // Add your business logic 
    } 
} 

Ausgang:

creating service 
Callable:1:pool-1-thread-1 
Call back:1 
Callable:2:pool-1-thread-2 
Call back:2 
Callable:8:pool-1-thread-8 
Call back:8 
Callable:3:pool-1-thread-3 
Call back:3 
Callable:10:pool-1-thread-10 
Callable:4:pool-1-thread-4 
Call back:10 
Callable:7:pool-1-thread-7 
Call back:7 
Callable:6:pool-1-thread-6 
Call back:6 
Callable:9:pool-1-thread-9 
Callable:5:pool-1-thread-5 
Call back:9 
Call back:4 
Call back:5 

Zusammenfassung:

  1. ersetzen Manager mit ExecutorService Ihrer bevorzugten Wahl.
  2. Entweder können Sie Callaback Objekt an Callable/Runnable Objekt übergeben oder Sie können Callback Objekt innerhalb Callable/Runnable erstellen. In meinem Beispiel habe ich Callback Objekt explizit an Callable übergeben.
  3. Bevor das Ergebnis zurückgegeben wird, ruft Callable Objekt Callback Methode auf. Wenn Sie die Weiterverarbeitung blockieren möchten, außer Sie erhalten eine Antwort vom aktuellen Ereignis, kommentieren Sie einfach unter Zeile.

    System.out.println("future status:"+future.get()+":"+future.isDone()); 
    

Ich glaube, Sie es zu vermeiden, gehen und daher halten über der Linie kommentiert. Sie müssen keinen neuen Thread für den Methodenaufruf Callback erstellen. Wenn Sie das Ereignis Callback asynchron verarbeiten möchten, können Sie ein weiteres ExecutorService erstellen und das Ereignis absenden.

2

Ich hätte den Thread, der die Aufgabe ausführt, führen Sie auch den Rückruf aus. Anstatt jedes Mal einen Thread zu erstellen, schlage ich vor, dass Sie einen ExecutorService verwenden.

public static <T> void submit(ExecutorService service, 
           Callable<T> callable, 
           Consumer<T> callback) { 
    service.submit(() -> { 
     try { 
      callback.accept(callable.call()); 
     } catch (Throwable t) { 
      // log the Throwable 
     } 
    }); 
} 
+0

Die Task wird "off-device" ausgeführt. Dies ist ein Manager für BLE-Kommunikation. Sobald die Antwort über BLE empfangen wurde, wird der Rückruf ausgeführt. Daher das Erschaffen eines Threads dafür. – AmiguelS

+0

@AmiguelS Sie können immer noch einen Thread-Pool für diese Rückrufe verwenden. Wenn Sie eine Kommunikationsbibliothek haben, hat diese normalerweise einen Thread für Rückrufe/Benachrichtigung von Nachrichten. –

Verwandte Themen