2016-04-06 60 views
3

在此項目上,Manager執行事件排隊,並返回使用回調的事件結果(回調未延伸Runnable)。經理在一個單獨的線程上運行,分派事件。一旦事件終止,同一個線程會調用回調函數。這意味着在前一個事件的回調結束之前,下一個事件不會被分派。爲了避免這種情況,我要讓管理者爲每個回調創建一個新的線程,並在那裏執行回調。這個解決方案在設計實踐方面有多好,是否有更好的方法來實現這一點?在新線程上執行Java回調

回答

5

簡單Callback代碼:

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 
    } 
} 

輸出:

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 

總結:

  1. 替換Manager與首選的ExecutorService
  2. 您可以將Callaback對象傳遞給Callable/Runnable對象或者您可以在Callable/Runnable中創建Callback對象。在我的示例中,我明確將Callback對象傳遞給Callable
  3. 在返回結果之前,Callable對象調用Callback方法。如果您想阻止繼續進行,除非您獲得當前事件的響應,請在下面的行中取消註釋。

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

我認爲你要避免它,從而保持上面一行註釋。您不必爲Callback方法調用創建新線程。如果您想要異步處理Callback事件,則可以再創建一個ExecutorService並提交事件。

2

我會有執行任務的線程,也執行回調。而不是每次創建一個線程,我建議你使用一個ExecutorService。

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

該任務執行「off-device」。這是BLE通信的經理。一旦通過BLE接收到響應,就會執行回調。因此,儘管爲它創建了一個線程。 – AmiguelS

+0

@AmiguelS你仍然可以爲這些回調使用線程池。如果你有一個通信庫,它通常有一個線程用於回調/通知消息。 –