要处理大量数据,我试图让它们并行。
class Item{
Integer id;
String data;
}
ExecutorService executor = Executors.newFixedThreadPool(10);
for (Item item : items) {
executor.execute(() -> putItemToDB(item));
}
但是发生的问题是,在测试用例中,我有前6个任务到同一个主键。具有相同主键(id)的任务顺序很重要,不得更改。目前,我不能保证这一点。
示例:
items = [{id: 1, data: "a"}, {id: 1, data: "b"}, {id: 2, data: "g"}]
我必须知道a
在 b
之前是,并且在线程池中运行所有任务并不能保证这一点。有可能a
会覆盖b
。
有没有好的设计模式来解决这个问题?
答案 0 :(得分:1)
此用例的良好设计模式是为每个id使用单独的Actor实例。项目被发送到相应的actor并在输入队列中按顺序保存。 Actor从队列中获取下一个项目并保存在数据库中。 要查找键的actor,可以使用HashMap。
如果有太多不同的ID以及太多的actor,actor可以检查输入队列是否为空一段时间,然后从HashMap中注销自己。
此外,可以优化这样的actor,以便可以使用单个项的变量而不是输入队列。如果在上一个项目尚未写入数据库时另一个项目到达,则新项目只会重写上一个项目 - 无论如何,编写旧项目没有任何意义,它将被覆盖在数据库中。
可以在https://github.com/rfqu/CodeSamples/blob/master/src/simpleactor/SimpleActor.java
找到一个简单的演员