有大量数据需要处理,我试图使它们并行。
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
。
有什么好的设计模式可以解决这个问题吗?
最佳答案
此用例的良好设计模式是为每个 id 使用单独的 Actor 实例。项目被发送到相应的参与者并按顺序保存在输入队列中。 Actor 从队列中取出下一个项目并将其保存在数据库中。 要查找键的参与者,可以使用 HashMap。
如果有太多不同的 id 和太多的 actor,actor 可以检查其输入队列是否为空一段时间,然后从 HashMap 中注销自己。
还可以优化这样的参与者,以便可以使用单个项目的变量来代替输入队列。如果在前一个项目尚未写入数据库时另一个项目到达,新项目只会重写前一个项目 - 无论如何,写入旧项目没有任何意义,它将在数据库中被覆盖。
可以在https://github.com/akaigoro/CodeSamples/blob/master/src/main/java/actor/simpleactor/SimpleActor.java找到一个简单的 Actor 开始
关于java - 具有主键保留序列更新的数据库多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44920327/