需要算法来执行特定客户按顺序提交的任务

时间:2016-06-10 04:21:24

标签: java multithreading algorithm performance

需要高性能算法:

场景:以非常频繁的间隔在线程池中为不同的客户提交任务 要求:任务需要由特定客户按顺序提交,但不同客户提交的不同任务可以并行执行。

2 个答案:

答案 0 :(得分:0)

以下是如何编写工人类的示例。 worker类保留当前正在处理的所有客户的并发映射。只要工作人员从列表中获取下一个工作项,它就会检查该客户当前是否正在处理中。如果是这样,它会在队列末尾重新排队任务。

如果您有任何问题,请与我们联系。

public class MyWorker extends Thread {
    private static int instance = 0;
    private final Queue<Task> queue;
    // This is used to hold the customer that are in process at this time.
    private final ConcurrentHashMap<String, Boolean> inProcessCustomers;

    public MyWorker(Queue queue, ConcurrentHashMap<String, Boolean> inProcessCustomers) {
        this.queue = queue;
        this.inProcessCustomers = inProcessCustomers
        setName("MyWorker:" + (instance++));
    }

    @Override
    public void run() {
        while ( true ) {
            try {
                Runnable work = null;

                synchronized ( queue ) {
                    while ( queue.isEmpty() )
                        queue.wait();
                    // Get the next work item off of the queue
                    task = queue.remove();
                    // if the customer is in process, then add the task back to the end of the queue and return.
                    if(inProcessCustomers.containsKey(task.getCustomerId()) {
                      queue.add(task);
                      return;
                    }
                    inProcessCustomer.put(task.getCustomerId(), true);
                }

                // Process the work item
                task.run();
                inProcessCustomer.remove(task.getCustomerId());
            }
            catch ( InterruptedException ie ) {
                break;  // Terminate
            }
        }
    }

    private void doWork(Runnable work) { ... }
}

答案 1 :(得分:-1)

听起来您需要一种将客户映射到任务队列的方法。

假设:每个客户都有一种独特的识别方式。

我建议在代表客户的任何对象上实施hashCode method

在提交任务时,您创建一个映射(使用HashMap),其中密钥是您的客户,值是队列 - 我建议ConcurrentLinkedQueue - 然后添加任务或线程到队列。在处理任务时,从队列中删除它们(或根据设计选择的线程)。

编辑: 为了继续讨论,我将假设任务将是存储在队列中的对象。

上面我写的时候#34;当你处理任务时删除它们......&#34;我的意思是任务将保留在队列中直到完成。您可以使用队列的peek方法执行此操作。

关于如何在将任务添加到队列后处理任务,可以为任务提供对队列对象的引用,以便一旦任务完成,它就可以触发下一个任务。这篇文章的基本算法是这样的:负责向队列添加任务的控制器线程将检查队列是否为空。如果队列不为空,则只会将下一个任务添加到队列中,因为当前任务完成时会触发下一个任务。如果队列为空,则控制器会触发下一个任务 - 它应该已经引用了该任务。当前任务完成后,它将调用其队列的poll方法将其自身从队列的头部移除,然后调用peek以获取下一个任务。然后执行下一个任务。