需要高性能算法:
场景:以非常频繁的间隔在线程池中为不同的客户提交任务 要求:任务需要由特定客户按顺序提交,但不同客户提交的不同任务可以并行执行。
答案 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以获取下一个任务。然后执行下一个任务。