如何在定义的线程(池)上 运行 class 的方法?

How to run the methods of a class on a defined thread(pool)?

我正在编写 classes 系列,全部使用相机。 每个class有4个基本方法来初始化、启动、停止或释放相机。

我想运行这些方法在后台线程。但我正在努力寻找一种简单的方法来做到这一点。

我发现的唯一方法是使用定义为

的通用 ExecutorService
ExecutorService backgroundThread = Executors.newSingleThreadExecutor();

然后,我必须 将每个方法的代码 包装成这样:

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

我想有更聪明的方法可以做到这一点,但我不知道。有人有办法做到这一点吗?

谢谢

您可以使用 Queue 方法调用以及 Router 来确定要调用哪个 class 方法:

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 移动到 [=12] =](因此 Router 不再实现 Runnable 而是创建内部 Runnables 来处理队列)。

您可以创建一个包含这些方法的 'async' 版本的摘要 parent class。

从一个抽象的 parent class 开始,然后将它们中的每一个都包装在它们自己的 运行nable 异步版本中。现在,每当您从抽象 parent 继承时,每个都会自动拥有自己的 运行nable。然后您可以将它们放入执行程序或 parent.

中您需要的任何内容
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;
    }
}

这将为您正在编写的整个 classes 系列提供一个良好的基础,而无需将 Runnable 随处放置。

如果您想在后台线程上强制所有这些 运行,请保护抽象方法。然后将您的执行程序服务放在 parent class 中,而不是返回 Runnable,而是在执行程序服务中启动它。

您的每个 child classes 现在都自动具有所有异步操作,但您只需实施四种方法即可实现。