【问题标题】:Need algo for executing tasks sequentially submitted by a particular customer执行特定客户按顺序提交的任务的需要算法
【发布时间】:2016-10-10 22:13:37
【问题描述】:

需要高性能算法:

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

【问题讨论】:

  • 在 C# 中可以创建一个Dictionary<int, Task>,然后使用ContinueWith。如果听起来很有趣,我可以告诉你怎么做。
  • 问题是什么?

标签: java multithreading algorithm performance


【解决方案1】:

这是一个如何编写工人类的示例。工人类保持当前正在处理的所有客户的并发地图。每当工作人员从列表中取出下一个工作项时,它都会检查该客户当前是否正在处理中。如果是这样,它会将任务重新排入队列末尾。

如果您有任何问题,请告诉我。

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) { ... }
}

【讨论】:

  • 谢谢 Piyg,我在您的代码中看到了一些问题,因为您正在从队列中删除任务,然后检查 isInProcess,然后再次放回,这将导致任务结束队列,因此执行顺序不保持为队列中可能有来自同一客户的其他任务,希望你明白我的意思,但主要问题是性能我想在高延迟实时解决方案中使用它,所以它不会工作我正在寻找一些现有的具有性能的算法
【解决方案2】:

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

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

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

提交任务时,您创建一个映射(使用HashMap),其中键是您的客户,值是队列——我建议ConcurrentLinkedQueue——然后将任务或线程添加到队列中。当您处理任务时,从队列中删除它们(或它们的线程,取决于设计选择)。

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

当我写“当你处理任务时删除它们......”时,我的意思是任务将保留在队列中直到完成。您可以使用队列的peek 方法来执行此操作。

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

【讨论】:

  • 感谢 DB 的回答
  • 哦,但是有一个问题,您将如何处理将任务放入队列后,您能解释一下吗?
  • 答案并没有说明这里的核心问题。这就是如何根据customerId对工作进行序列化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多