Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在已定义的线程(池)上运行类的方法?_Java_Android_Multithreading_Threadpool - Fatal编程技术网

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

Java 如何在已定义的线程(池)上运行类的方法?,java,android,multithreading,threadpool,Java,Android,Multithreading,Threadpool,我正在写一个系列的课程,都是用相机写的每个类有4个基本方法初始化、启动、停止或释放相机 我想在后台线程中运行这些方法。但我正在努力找到一个简单的方法来做到这一点 我发现的唯一方法是使用一个定义为 ExecutorService backgroundThread = Executors.newSingleThreadExecutor(); 然后,我必须将每个方法的代码围绕如下内容进行包装: public void start(){ AbstractLight.backgroundThre

我正在写一个系列的课程,都是用相机写的每个类有4个基本方法初始化、启动、停止或释放相机

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

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

ExecutorService backgroundThread = Executors.newSingleThreadExecutor();
然后,我必须将每个方法的代码围绕如下内容进行包装:

public void start(){
    AbstractLight.backgroundThread.execute(new Runnable(){
        public void run(){
            //write "start method" code here
        }
    });
}
我想有一个更聪明的方法,但我不知道。有人会耍花招吗


谢谢

您可以使用方法调用的
队列以及
路由器来确定要调用哪个类的方法:

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;
    }
  }
}
公共接口摄像机{
公共void init();
公共无效开始();
公共停车位();
公开无效释放();
}
公共类路由器实现可运行{
私有最终EnumMap摄影机=新EnumMap(CameraType.class);
private final BlockingQueue=新建LinkedBlockingQueue();
公共枚举摄影机类型{
摄像机1,摄像机2,等等
}
私有枚举摄像方法{
初始化、启动、停止、释放
}
私人职业{
公共最终摄像机;
公共最终摄影师法;
公共路线职业(摄像机c、摄像法cm){
这个相机=c;
本.摄像方法=厘米;
}
}
//启动、停止、释放的类似方法
公共void init(CameraType CameraType){
queue.offer(新路由职业(cameras.get(cameraType),INIT);
}
公开募捐{
试一试{
while(true){
//等待下一个假期
RouterInvocation i=queue.take();
if(i.cameraType==INIT){
i、 camera.init();
}else if//其余方法相同
}
}捕获(中断异常例外){
回来
}
}
}
这样做的好处是,您只需将一个
Runnable
Router
)提交给
ExecutorService
)-然后
Router
负责从相应的
摄像机
实现中调用相应的方法


如果您决定需要多个线程处理队列,那么您可以在多个
路由器
之间共享队列,或者我的建议是将
ExecutorService
移动到
路由器
(因此
Router
不再实现
Runnable
,而是创建内部
Runnables
来处理队列)。

您可以使用方法调用的
队列以及
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;
    }
  }
}
公共接口摄像机{
公共void init();
公共无效开始();
公共停车位();
公开无效释放();
}
公共类路由器实现可运行{
私有最终EnumMap摄影机=新EnumMap(CameraType.class);
private final BlockingQueue=新建LinkedBlockingQueue();
公共枚举摄影机类型{
摄像机1,摄像机2,等等
}
私有枚举摄像方法{
初始化、启动、停止、释放
}
私人职业{
公共最终摄像机;
公共最终摄影师法;
公共路线职业(摄像机c、摄像法cm){
这个相机=c;
本.摄像方法=厘米;
}
}
//启动、停止、释放的类似方法
公共void init(CameraType CameraType){
queue.offer(新路由职业(cameras.get(cameraType),INIT);
}
公开募捐{
试一试{
while(true){
//等待下一个假期
RouterInvocation i=queue.take();
if(i.cameraType==INIT){
i、 camera.init();
}else if//其余方法相同
}
}捕获(中断异常例外){
回来
}
}
}
这样做的好处是,您只需将一个
Runnable
Router
)提交给
ExecutorService
)-然后
Router
负责从相应的
摄像机
实现中调用相应的方法


如果您决定需要多个线程处理队列,那么您可以在多个
路由器
之间共享队列,或者我的建议是将
ExecutorService
移动到
路由器
(因此
Router
不再实现
Runnable
,而是创建内部
Runnables
来处理队列)。

您可以创建一个包含这些方法的“异步”版本的抽象父类

从一个抽象父类开始,并将它们包装在各自的可运行异步版本中。现在,每当您从抽象父类继承时,每个类都将自动拥有自己的可运行。然后,您可以将它们放入执行器中,或者从父类中获取所需的任何内容

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;
    }
}
这将为您正在编写的整个类家族提供一个良好的基础,而无需到处放置可运行程序

如果要强制所有这些在后台线程上运行,请保护抽象方法。然后将executor服务放在父类中,而不是返回Runnable,而是在executor服务中启动它


现在,您的每个子类都自动执行所有异步操作,但您只需实现这四个方法即可。

您可以创建一个抽象父类,其中包含这些方法的“异步”版本

从一个抽象父类开始,并将它们包装在各自的可运行异步版本中。现在,每当您从抽象父类继承时,每个类都将自动拥有自己的可运行。然后,您可以将它们放入执行器中,或者从父类中获取所需的任何内容

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;
    }
}
这将为你的整个班级打下良好的基础