多个线程,同时分页查询数据库每次 1000 条,然后 java 程序过滤这一千条数据,将满足条件的数据被 add 一个新集合里面,这个集合每 100 条输出一次 Excel。
我隐约记得 java 的某些集合的 add 操作不是线程安全的,有些并发容器 size 判断会不准确。还得满足条件 100 条输出一次(此时 add 操作应该会暂停),不足 100 条等待下一次 1000 条查询。
请问这种需求应该如何设计多线程? java 有否这种生产者模式的 api,类库等。
多个线程,同时分页查询数据库每次 1000 条,然后 java 程序过滤这一千条数据,将满足条件的数据被 add 一个新集合里面,这个集合每 100 条输出一次 Excel。
我隐约记得 java 的某些集合的 add 操作不是线程安全的,有些并发容器 size 判断会不准确。还得满足条件 100 条输出一次(此时 add 操作应该会暂停),不足 100 条等待下一次 1000 条查询。
请问这种需求应该如何设计多线程? java 有否这种生产者模式的 api,类库等。
1
sundae91 Mar 18, 2019
CopyOnWriteArrayList?
|
2
kiddult Mar 18, 2019
生产者+消费者,消费者单线程执行
|
3
momocraft Mar 18, 2019
java.util.concurrent 有线程安全的容器
|
4
rockyou12 Mar 18, 2019 你查数据库量级多少,查询条件复杂不?如果不复杂量,量级就万来条你单线程不分页可能还快些。
如果你 Java 里过滤条件比较耗时,直接用 parallelStream().filter().sequential() 这样结果也是保证顺序的 |
5
peyppicp Mar 18, 2019 首先 new 一个 Object 作为互斥量,创建一个 LinkedList 或者什么,两个方法一个写入数据,一个读取数据,针对这个 Object 上锁。取数据得时候 for 循环到 100 条之后退出循环即可
对于数据库查询 1000 条数据,然后过滤的需求,使用线程池搞定,向线程池提交 Future,然后在 Future 里对数据进行处理,然后调用写入数据的方法写入数据 如果想准确得知 list 的 size,就直接包装一层,先拿锁,再调用 list.size 方法。就我看来读取数据库时间应该远超锁切换时间,应该是值得的 不知道我讲清楚了没有。。 |
6
peyppicp Mar 18, 2019
其实性能不重要的场景 用不用并发容器都无所谓,自己用 sync 关键字包一层就完事了
|
7
mmdsun OP |
8
Lattez Mar 18, 2019
看了一眼之前写的,也是分页 1000 查的数据写 Excel,用的是 CopyOnWriteArrayList,当然这玩意本身底层实现就是 add 的时候上锁拷贝的
|
9
Weixiao0725 Mar 18, 2019
这个用条件变量可以实现吧
|
10
JohnZorn Mar 18, 2019 via Android
都说生产者消费者了,阻塞队列不行吗?有个什么 blockinglinkedqueue?
|
11
JohnZorn Mar 18, 2019 via Android
#10 LinkedBlockingQueue
|
12
mccreefei Mar 18, 2019
每个线程处理 1000 条,每过滤出 100 条有效数据封装一下塞到阻塞队列里,多余的数据加锁暂时存放到 list 中,消费者线程从阻塞队列里 100 条、100 条地拿数据写 excel,利用 countDownLatch,最后一个生产者线程处理那个 list ( list 中每 100 条塞阻塞队列)。
|