Java Runnable Queue

2020-07-23 06:05发布

I need peer reviews of the critical piece of code below.

This class maintain a queue of runnable objets, and ensure they are executed sequentially, that is, start one new after the previous one is completed until there is no more task in the queue.

I'm pretty sure it does, but I'm must be absolutely sure it behave as intented.

Many thanks !

public final class RunnableQueue {

    private final ExecutorService m_executorService;
    private final Queue<Runnable> m_runnables;
    private final Runnable m_loop;

    public RunnableQueue(ExecutorService executorService) {
        m_executorService = executorService;
        m_runnables = new LinkedList<Runnable>();

        m_loop = new Runnable() {
            public void run() {

                Runnable l_runnable = current();

                while(l_runnable != null) {
                    l_runnable.run();
                    l_runnable = next();
                }
            }
        };
    }

    private Runnable current() {
        synchronized (m_runnables) {
            return m_runnables.peek();
        }
    }

    private Runnable next() {
        synchronized (m_runnables) {
            m_runnables.remove();
            return m_runnables.peek();
        }
    }

    public void enqueue(Runnable runnable) {
        if(runnable != null) {
            synchronized (m_runnables) {
                m_runnables.add(runnable);
                if(m_runnables.size() == 1) {
                    m_executorService.execute(m_loop);
                }
            }
        }
    }
}

Edit

Basicaly, there will be hundreds of RunnableQueue instanciated using the same ThreadPool and each Runnable executed may add other Runnable in other RunnableQueue.

So, new Runnable will be added to the RunnableQueue while it runs...

2条回答
祖国的老花朵
2楼-- · 2020-07-23 06:47

Obvious question: Why do you use Runnables (threads) while you do not want to execute those threads in parallel?

If the idea is to execute the items in the queue in parallel to something else, you could consider using only one thread (runnable) that executes all commands in the queue in a sequence:

private Queue<Command> queue = initQueue();

public run() {
  while(!stop) {
    Command nextCommand = queue.pop();
    nextCommand.execute();
  }
}

Command is a custom interface with just one single method. (Note: this simple example expects that the queue is never empty)

查看更多
趁早两清
3楼-- · 2020-07-23 06:52

Any reason you don't use fixed thread pool with a single thread?

ExecutorService service = Executors.newFixedThreadPool(1);

submitting Runnables to service will do exactly what you want as the service operates off a queue.

查看更多
登录 后发表回答