2015-06-22 42 views
1

我在寫一個類的家庭,都使用相機。 每個班級有4種基本方法來初始化,啓動,停止或釋放攝像頭。我想在後臺線程中運行這些方法。但我正在努力尋找一個簡單的方法來做到這一點。如何在定義的線程(池)上運行類的方法?

我發現的唯一方法是使用共同的ExecutorService定義爲

ExecutorService backgroundThread = Executors.newSingleThreadExecutor(); 

然後,我已到包裝每個單個方法的代碼周圍是這樣的:

public void start(){ 
    AbstractLight.backgroundThread.execute(new Runnable(){ 
     public void run(){ 
      //write "start method" code here 
     } 
    }); 
} 

我想有一個更聰明的方法來做到這一點,但我不知道。有人有一個伎倆來做到這一點?

謝謝

回答

3

您可以創建一個包含這些方法的「異步」版本的抽象父類。

從一個抽象父類開始,並將它們中的每一個包裝在它們自己的可運行的異步版本中。現在,無論何時您從抽象父項繼承,每個都將自動擁有自己的可運行。然後,您可以將它們放入執行程序或您父母需要的任何內容。

public abstract class CameraParent 
{ 
    public abstract void init(); 
    public abstract void start(); 
    public abstract void stop(); 
    public abstract void release(); 

    public virtual Runnable initAsync() 
    { 
     Runnable r = new Runnable() 
     { 
      @Override 
      public void Run() 
      { 
       init(); 
      } 
     } 
     return r; 
    } 

    public virtual Runnable startAsync() 
    { 
     Runnable r = new Runnable() 
     { 
      @Override 
      public void Run() 
      { 
       start(); 
      } 
     } 
     return r; 
    } 

    public virtual Runnable stopAsync() 
    { 
     Runnable r = new Runnable() 
     { 
      @Override 
      public void Run() 
      { 
       stop(); 
      } 
     } 
     return r; 
    } 

    public virtual Runnable releaseAsync() 
    { 
     Runnable r = new Runnable() 
     { 
      @Override 
      public void Run() 
      { 
       release(); 
      } 
     } 
     return r; 
    } 
} 

這會給你的你寫,類整個家庭了良好的基礎,而不放置的Runnable無處不在。

如果您想要強制所有這些在後臺線程上運行,請使抽象方法受保護。然後將您的執行器服務放在父類中,而不是返回Runnable,請在執行器服務中啓動它。

您的每個子類現在都會自動完成所有的異步操作,但您只需實現四種方法即可實現該操作。

2

您可以使用方法調用的Queue以及一個Router來確定哪些類的方法來調用:

public interface Camera { 
    public void init(); 
    public void start(); 
    public void stop(); 
    public void release(); 
} 

public class Router implements Runnable { 
    private final EnumMap<CameraType, Camera> cameras = new EnumMap<>(CameraType.class); 
    private final BlockingQueue<RouterInvocation> queue = new LinkedBlockingQueue<>(); 

    public enum CameraType { 
    CAMERA1, CAMERA2, //etc 
    } 

    private enum CameraMethod { 
    INIT, START, STOP, RELEASE 
    } 

    private class RouterInvocation { 
    public final Camera camera; 
    public final CameraMethod cameraMethod; 
    public RouterInvocation(Camera c, CameraMethod cm) { 
     this.camera = c; 
     this.cameraMethod = cm; 
    } 
    } 

    // similar methods for start, stop, release 
    public void init(CameraType cameraType) { 
    queue.offer(new RouterInvocation(cameras.get(cameraType), INIT); 
    } 

    public void run() { 
    try { 
     while(true) { 
     // wait for next RouterInvocation 
     RouterInvocation i = queue.take(); 
     if(i.cameraType == INIT) { 
      i.camera.init(); 
     } else if // same for remaining methods 
     } 
    } catch(InterruptedException ex) { 
     return; 
    } 
    } 
} 

的好處是,你只需要提交一個RunnableRouter)與ExecutorService - Router然後負責從適當的Camera實施調用適當的方法。

如果你決定要多線程處理隊列中,那麼你可以共享隊列多個Routers之間,或者我的建議是移動ExecutorService內的Router(所以Router不再實行Runnable而是創建內部Runnables來處理隊列)。

+0

謝謝,我會檢查一下。 – Gordak

+0

處理程序也可能類似地工作 – Sam

相關問題