Очередь, которая потребляет объекты одного интерфейса и выполняет работу в замке - PullRequest
0 голосов
/ 24 апреля 2018

сообщество!

Мне нужно реализовать некую Очередь, которая будет принимать объекты одного интерфейса, давайте назовем этот интерфейс Команда и последовательно выполню их работу.

Например, у меня есть интерфейс Команда вот так

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().

Я добавлю все больше и больше классов, которые будут реализовывать Command в будущем.

Существуют ли уже подобные вещи, уже реализованныев Android или кто-нибудь может предоставить некоторые фрагменты кода?

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Как уже говорилось, вы можете использовать экземпляр 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());

}
0 голосов
/ 24 апреля 2018

Поскольку вы хотите выполнять эти команды в порядке последовательности, я бы предложил использовать шаблон Producer-Consumer, для этого можно использовать два потока и очередь блокировки.

По сути, производитель попытается поместить новые 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();
            }
        }
    }
}
...