如何实现一个可运行的队列[英] How to implement a queue of runnables

本文是小编为大家收集整理的关于如何实现一个可运行的队列的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在尝试实现一个可运行的队列以接一个地执行(这意味着在异步任务中,在另一个队伍完成后将在队列中执行下一个).我写了一位经理来管理这些可运行的运行功能和任务.然后,我在异步任务中获得了第一个任务,并希望它可以通过队列运行,但是它最终仅运行了第一个可运行的两次.谁能帮助我处理与我一起工作的代码,或者指出我可能会有所帮助的示例?

public class ConnectionManager {

    public static final int MAX_CONNECTIONS = 15;

    private ArrayList<Runnable> active = new ArrayList<Runnable>();
    private ArrayList<Runnable> queue = new ArrayList<Runnable>();

    private static ConnectionManager instance;

    public static ConnectionManager getInstance() {
        if (instance == null)
            instance = new ConnectionManager();
        return instance;
    }

    public void push(Runnable runnable) {
        queue.add(runnable);
        if (active.size() < MAX_CONNECTIONS)
            startNext();
    }

    private void startNext() {
        if (!queue.isEmpty()) {
            Runnable next = queue.get(0);
            queue.remove(0);
            active.add(next);

            Thread thread = new Thread(next);
            thread.start();
        }
    }

    public void didComplete(Runnable runnable) {
        active.remove(runnable);
        startNext();
    }
}

public class Task implements Runnable {
    Context con;
    String xmlFile;
    File taskFile;
    String Id;

    public void create(Context context, String xml, File task, String id) {
        this.con = context;
        this.xmlFile = xml;
        this.taskFile = task;
        this.Id = id;
        ConnectionManager.getInstance().push(this);
    }

    @Override
    public void run() {
        User.SendTask(con, xmlFile, taskFile, Id);

        ConnectionManager.getInstance().didComplete(this);
    }

推荐答案

使用opecutors.newsinglethreadexecutor()怎么样? 其他推荐答案

我在一个应用程序中做的事情非常相似,我要保持清洁的方法是使我的队列包含数据,而不是要执行的线程.我使用单个asynctask进行执行(从系统分配的线程池中拉出...可能会使您更容易为您提供MGMT),并且在Doinbackground方法中,我将数据从队列中拉出,在其上删除,然后在其上操作,并在Onpostexecute中再次致电我的输入方法.

其他推荐答案

无需自己构建它,只需使用 ThreadPoolExecutor 为您做.构造一个小矮人大小为1,最大池大小为15,您应该全部设置.

本文地址:https://www.itbaoku.cn/post/102384.html

问题描述

I am trying to implement a queue of runnables to be executed one after another(meaning the next in the queue will execute after the other has completed) during an asynchronous task. I wrote a Manager to manage these runnables and task that is a runnable itself. I then get the first task in the Asynchronous task and run it in hopes that it will run through the queue, however It just ends up running the first runnable twice. Can anyone help me with the code I have been working with or point me to an example that may be of some help?

public class ConnectionManager {

    public static final int MAX_CONNECTIONS = 15;

    private ArrayList<Runnable> active = new ArrayList<Runnable>();
    private ArrayList<Runnable> queue = new ArrayList<Runnable>();

    private static ConnectionManager instance;

    public static ConnectionManager getInstance() {
        if (instance == null)
            instance = new ConnectionManager();
        return instance;
    }

    public void push(Runnable runnable) {
        queue.add(runnable);
        if (active.size() < MAX_CONNECTIONS)
            startNext();
    }

    private void startNext() {
        if (!queue.isEmpty()) {
            Runnable next = queue.get(0);
            queue.remove(0);
            active.add(next);

            Thread thread = new Thread(next);
            thread.start();
        }
    }

    public void didComplete(Runnable runnable) {
        active.remove(runnable);
        startNext();
    }
}

public class Task implements Runnable {
    Context con;
    String xmlFile;
    File taskFile;
    String Id;

    public void create(Context context, String xml, File task, String id) {
        this.con = context;
        this.xmlFile = xml;
        this.taskFile = task;
        this.Id = id;
        ConnectionManager.getInstance().push(this);
    }

    @Override
    public void run() {
        User.SendTask(con, xmlFile, taskFile, Id);

        ConnectionManager.getInstance().didComplete(this);
    }

推荐答案

how about using Executors.newSingleThreadExecutor()? http://developer.android.com/reference/java/util/concurrent/Executors.html#newSingleThreadExecutor%28java.util.concurrent.ThreadFactory%29

API description explains that this executor execute only one task sequentially and has unlimited queue. I think this one can satisfies your requirement.

其他推荐答案

I'm doing something very similar in one of my apps, and what I do to keep it clean is to make my queue contain the data and not the threads to execute. I use a single AsyncTask for my execution (which pulls from a thread pool that the system allocates...might make mgmt easier for you), and in the doInBackground method of it, I pull data out of the queue, operate on it, and call my entry method again in onPostExecute.

其他推荐答案

There's no need to build this yourself, just use a ThreadPoolExecutor to do it for you. construct one with a minPool size of 1, and a max pool size of 15, and you should be all set.