【问题标题】:How to run the methods of a class on a defined thread(pool)?如何在定义的线程(池)上运行类的方法?
【发布时间】:2015-09-08 00:34:40
【问题描述】:

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

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

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

ExecutorService backgroundThread = Executors.newSingleThreadExecutor();

然后,我必须将每个方法的代码包装,如下所示:

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

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

谢谢

【问题讨论】:

    标签: java android multithreading threadpool


    【解决方案1】:

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

    从一个抽象父类开始,然后将每个类包装在它们自己的可运行异步版本中。现在,每当您从抽象父级继承时,每个都将自动拥有自己的可运行文件。然后,您可以将它们放入 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;
        }
    }
    

    这将为您编写的整个类家族提供一个良好的基础,而无需到处放置 Runnables。

    如果您想强制所有这些在后台线程上运行,请保护抽象方法。然后将您的执行器服务放在父类中,而不是返回 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;
          }
        }
      }
      

      好处是您只需向ExecutorService 提交一个RunnableRouter) - 然后Router 负责从适当的Camera 实现中调用适当的方法。

      如果您决定让多个线程处理队列,那么您可以在多个Routers 之间共享队列,或者我的建议是将ExecutorService 移动到Router 内部(所以Router 不更长的实现Runnable 而是创建内部Runnables 来处理队列)。

      【讨论】:

      • 谢谢,我去看看。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-03
      • 2011-05-14
      • 2011-09-30
      • 1970-01-01
      相关资源
      最近更新 更多