我为客户提供任务。每个客户都有一个ID。我希望来自一个客户的所有任务(即相同的ID)按顺序处理,而不是同时处理。但是,同时处理两个不同的客户是完全可以的。
处理由具有许多线程的ThreadPoolExecutor完成。我应该如何修改Queue或ThreadPoolExecutor,以便每当提交任务时,首先检查是否有相同的ID另一个任务已经在运行,在这种情况下,它会处于某种等待状态。
注意:jkeylockmanager(https://code.google.com/p/jkeylockmanager/)朝着正确的方向前进,但它只管理每个ID的锁,而不是线程选择。
答案 0 :(得分:1)
考虑保留已发出请求的客户ID的线程安全队列。然后,仅将客户ID提交给线程池。例如:
private void Reviews_browser_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// Determine if text has changed in the textbox by comparing to original text.
// Display a MsgBox asking the user to save changes or abort.
if (MessageBox.Show("Закрыть, сохранив загруженные БД?", "Внимание!",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// Cancel the Closing event from closing the form.
e.Cancel = false;
// Call method to save file...
}
else
{
e.Cancel = true;
try
{
string[] dirs = Directory.GetFiles(@Directory.GetCurrentDirectory(), "*.xml");
foreach (string dir in dirs)
{
if (Path.GetFileName(dir) != "HtmlAgilityPack.xml" && Path.GetFileName(dir) != ".xml")
{
int len = Path.GetFileName(dir).Length;
glavnaya.fayly_s_otzivami.Items.Add(Path.GetFileName(dir).Remove(len - 4, 4));
}
}
}
catch (Exception oshibocka)
{
}
}
然后,DoAllCustomerTasks customer1 = new DoAllCustomerTasks(1);
DoAllCustomerTasks customer2 = new DoAllCustomerTasks(2);
threadPool.submit(customer1);
threadPool.submit(customer2);
将实现DoAllCustomerTasks
,它将负责查找和执行与其构造的customerID相关的所有任务。
答案 1 :(得分:0)
可能有更好的解决方案,但如果: 而不是使用ThreadPoolExecutor,使用N个单线程执行程序的数组。 处理id = someId
的请求执行者[someId%N] .submit(task);
我们将除法提醒作为执行者索引,以确保具有相同ID的请求将由同一个线程处理