Jar*_*red 6 java multithreading thread-safety
我有一个对一组对象进行操作的任务队列(例如,为了示例,这些对象是地址簿中的条目).
示例任务可能是"将Joe的电话号码更新为888-555-1212".
同时在队列中有多个"更新Joe的电话号码......"任务,但电话号码不同.在这种情况下,必须应用更新以确保最后状态是正确的(并且,为了参数,不能将时间戳放在通讯簿条目上的任务和时间戳上并扔掉陈旧的任务).
使用Joe的更新对Jane进行无序更新是安全的.
我想多线程处理队列,但我需要按人员同步访问.
这种东西有一个方便的库吗?或者我降级为使用Executor并在Runnable的run()方法中对"name"进行自己的同步?
Chr*_*ies -1
一种可能的解决方案
假设某个任务由某个类描述
class Task {
Integer taskGroup;
// other
}
Run Code Online (Sandbox Code Playgroud)
其中taskGroup是一个ID,它标识必须按到达顺序处理的任务(在您的示例中,每个“名称”可以定义自己的taskGroup - 或者更一般地说 - 具有相同名称的任务属于同一taskGroup)。
让mainTaskQueue表示ListTask 对象。然后
Map<Integer,List<Task>>,说taskGroupsQueuestaskGroupsQueues.get(taskGroup)。task从主任务列表中删除 amainTaskQueue并将其附加到taskGroups.get(task.taskGroup)换句话说:属于相同名称的任务在同一线程上执行。
注意,如果主线程执行任务的分配,那么他还可以执行某种负载平衡,即,如果一个任务由于顺序一致性而没有被强制到特定队列,则该任务应该进入shortes队列。然而,您的问题固有的是它可能会变成单线程 - 即当您只有属于同一任务组(以您的案例名称)的任务时。
另一个可能的解决方案 (未经测试,只是一个建议)
正如increment1s 帖子和Aurands 评论中所指出的,tread 内taskGroup(名称)的同步存在一些问题。基本上:为时已晚,因为执行器可能已经启动了两个尝试同步同名的线程。但是,您可以尝试确保执行器级别的执行顺序。例如,请参阅这篇文章:Java Executors:如何设置任务优先级?(它引用传递给执行器的 PriorityBlockingQueue)。