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