代码之家  ›  专栏  ›  技术社区  ›  Олег Місько

使用同一接口的对象并在锁中执行工作的队列

  •  -1
  • Олег Місько  · 技术社区  · 6 年前

    社区

    我需要实现某种队列,它将接受一个接口的对象,让我们调用这个接口 命令 并按顺序执行工作。

    例如,我有接口 命令 这样地

    public interface Command {
    
        public void execute();
    
    }
    

    我有一个类,它实现了这个接口

    public class BasicCommand implements Command {
        private int operationId;
    
        public BasicCommand(int operationId) {
            this.operationId = operationId;
        }
    
        @Override
        public void execute() {
            Log.d("BasicCommand", "Id: " + operationId);
        }
    }
    

    我需要一个队列,它将按顺序执行此命令并调用 execute() 方法

    我将添加越来越多的类,这些类将在将来实现命令。

    Android中是否已经实现了类似的功能,或者是否有人可以提供一些代码片段?

    2 回复  |  直到 6 年前
        1
  •  2
  •   nitnamby    6 年前

    如前所述,您可以使用 ExecutorService 实例并将命令作为任务提交给它。下面是一个示例实现。

    public class BasicCommand implements Command, Callable<Integer>{
    
    private int operationId;
    
    public BasicCommand(int operationId) {
        this.operationId = operationId;
    }
    
    public Integer call(){
        this.execute();
        return operationId;
    }
    
    @Override
    public void execute() {
        //Log.d("BasicCommand", "Id: " + operationId);
        System.out.println("hello executing command" + operationId);
    }
    
    public static void main(String[] args) throws Exception {
    
    
        ExecutorService exceutorService= Executors.newSingleThreadExecutor();
        exceutorService.submit(new BasicCommand(1));
        Future future =exceutorService.submit(new BasicCommand(2));
        System.out.println("result:" +future.get());
    
    }
    
        2
  •  1
  •   xingbin    6 年前

    由于您希望按顺序执行这些命令,我建议使用生产者-消费者模式,您可以使用两个线程和一个阻塞队列来实现这一点。

    基本上,制片人会尝试推出新的 Command 在队列中,消费者将尝试将其取出。阻塞队列将处理生产者和消费者之间的同步问题。

    例子:

    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingDeque;
    
    public class Main {
    
        public static void main(String[] args) throws Exception {
            BlockingQueue<Command> commands = new LinkedBlockingDeque<>();
            new Thread(new Consumer(commands)).start();
            new Thread(new Producer(commands)).start();
        }
    }
    
    class Consumer implements Runnable {
    
        BlockingQueue<Command> commands;
    
        public Consumer(BlockingQueue<Command> commands) {
            this.commands = commands;
        }
    
        @Override
        public void run() {
            Command command;
            try {
                while ((command = commands.take()) != null) {
                    command.execute();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    class Producer implements Runnable {
    
        BlockingQueue<Command> commands;
    
        public Producer(BlockingQueue<Command> commands) {
            this.commands = commands;
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    commands.put(new Command() {
                        @Override
                        public void execute() {
                            System.out.println("Command");
                        }
                    });
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }