Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/197.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.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_Collections_Queue - Fatal编程技术网

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

Java 正在使用同一接口的对象并在锁中执行工作的队列,java,android,multithreading,collections,queue,Java,Android,Multithreading,Collections,Queue,社区 我需要实现某种队列,它将接收一个接口的对象,让我们调用这个接口命令,并按顺序执行它们的工作 例如,我有这样的接口命令 public interface Command { public void execute(); } 我有一个类,它实现了这个接口 public class BasicCommand implements Command { private int operationId; public BasicCommand(int operation

社区

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

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

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中是否已经实现了类似的功能,或者是否有人可以提供一些代码片段?

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

基本上,生产者将尝试将新的
命令放入队列中,而消费者将尝试将其取出。阻塞队列将处理生产者和消费者之间的同步问题

例如:

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();
            }
        }
    }
}
import java.util.concurrent.BlockingQueue;
导入java.util.concurrent.LinkedBlockingDeque;
公共班机{
公共静态void main(字符串[]args)引发异常{
BlockingQueue commands=newlinkedblockingdeque();
新线程(新使用者(命令)).start();
新线程(新生产者(命令)).start();
}
}
类使用者实现Runnable{
阻塞队列命令;
公共使用者(阻止队列命令){
this.commands=命令;
}
@凌驾
公开募捐{
指挥部;
试一试{
而((command=commands.take())!=null){
command.execute();
}
}捕获(例外e){
e、 printStackTrace();
}
}
}
类生成器实现了Runnable{
阻塞队列命令;
公共生产者(封锁队列命令){
this.commands=命令;
}
@凌驾
公开募捐{
while(true){
试一试{
commands.put(新命令(){
@凌驾
public void execute(){
System.out.println(“命令”);
}
});
睡眠(1000);
}捕获(例外e){
e、 printStackTrace();
}
}
}
}

如前所述,您可以使用
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());

}
public类BasicCommand实现命令,可调用{
私有int操作ID;
公共基本命令(内部操作ID){
this.operationId=operationId;
}
公共整数调用(){
这是execute();
返回操作ID;
}
@凌驾
public void execute(){
//Log.d(“基本命令”,“Id:+操作Id”);
System.out.println(“hello executing command”+operationId);
}
公共静态void main(字符串[]args)引发异常{
ExecutorService exceutorService=Executors.newSingleThreadExecutor();
超额服务提交(新基本命令(1));
Future-Future=exceutorService.submit(新的基本命令(2));
System.out.println(“结果:+future.get());
}

您可以将这些命令提交给
ExecutorService
实例。它将执行这些命令。该命令需要实现一个
可运行的接口,并让
运行()方法调用
执行()
方法。这有意义吗?
队列
不执行任何操作,
队列
只是按照对象添加到队列的顺序对对象进行访问。@OldCurmudgeon,我没有说我需要队列对象,很抱歉描述不透明。我需要数据结构,这基本上是一个阻塞队列执行一些工作。@nitnamby,它能改为扩展Tread吗?@МГММіаimk_它能扩展
线程
,但实现
可运行
被认为更好。@user6690200只有一个线程执行任务,它不是并行的。我不需要并行执行这些任务,而是按顺序执行,因为我有一个这就是我在问题中使用术语“队列”的原因。我基本上添加了一些对象(假设它们实现了Runnable)然后他们一个接一个地执行他们的工作。如果一个开始工作,所有其他人都会等待。它不是并行执行的,因为只有一个线程。任务被添加到
阻塞队列
实现中,并由
执行器服务
按顺序执行。是的,当您通过
执行器创建它时。newSingleThreadExecutor()
,只有一个工作线程。@öСММіаааimk_
Future
表示任务异步计算的结果。'get()'将返回它的结果,是一个阻塞调用。如果需要返回某些内容,可以实现'Runnable'的'Callable'实例。我刚刚更新了答案