请教一 Java 多线程设计的问题

2019-03-18 10:32:19 +08:00
 mmdsun

多个线程,同时分页查询数据库每次 1000 条,然后 java 程序过滤这一千条数据,将满足条件的数据被 add 一个新集合里面,这个集合每 100 条输出一次 Excel。

我隐约记得 java 的某些集合的 add 操作不是线程安全的,有些并发容器 size 判断会不准确。还得满足条件 100 条输出一次(此时 add 操作应该会暂停),不足 100 条等待下一次 1000 条查询。

请问这种需求应该如何设计多线程? java 有否这种生产者模式的 api,类库等。

1816 次点击
所在节点    问与答
12 条回复
sundae91
2019-03-18 11:11:05 +08:00
CopyOnWriteArrayList?
kiddult
2019-03-18 11:15:44 +08:00
生产者+消费者,消费者单线程执行
momocraft
2019-03-18 11:19:37 +08:00
java.util.concurrent 有线程安全的容器
rockyou12
2019-03-18 11:23:14 +08:00
你查数据库量级多少,查询条件复杂不?如果不复杂量,量级就万来条你单线程不分页可能还快些。

如果你 Java 里过滤条件比较耗时,直接用 parallelStream().filter().sequential() 这样结果也是保证顺序的
peyppicp
2019-03-18 11:26:41 +08:00
首先 new 一个 Object 作为互斥量,创建一个 LinkedList 或者什么,两个方法一个写入数据,一个读取数据,针对这个 Object 上锁。取数据得时候 for 循环到 100 条之后退出循环即可

对于数据库查询 1000 条数据,然后过滤的需求,使用线程池搞定,向线程池提交 Future,然后在 Future 里对数据进行处理,然后调用写入数据的方法写入数据

如果想准确得知 list 的 size,就直接包装一层,先拿锁,再调用 list.size 方法。就我看来读取数据库时间应该远超锁切换时间,应该是值得的
不知道我讲清楚了没有。。
peyppicp
2019-03-18 11:34:12 +08:00
其实性能不重要的场景 用不用并发容器都无所谓,自己用 sync 关键字包一层就完事了
mmdsun
2019-03-18 12:09:58 +08:00
@sundae91 @kiddult @momocraft @rockyou12 @peyppicp

谢谢大家,目前打算使用加锁的方案。数据库查询还是比较耗时的操作。

看了几个 java 并发容器的 api 感觉场景不适合,比如 CopyOnWriteArrayList 用在读多写少的场景会更好。另外发现 java 的一些阻塞队列 api 应该可以做到,但由于不太熟悉 api 害怕会有什么坑。暂时打算加锁解决。
Lattez
2019-03-18 12:20:48 +08:00
看了一眼之前写的,也是分页 1000 查的数据写 Excel,用的是 CopyOnWriteArrayList,当然这玩意本身底层实现就是 add 的时候上锁拷贝的
Weixiao0725
2019-03-18 12:25:29 +08:00
这个用条件变量可以实现吧
choice4
2019-03-18 14:15:16 +08:00
都说生产者消费者了,阻塞队列不行吗?有个什么 blockinglinkedqueue?
choice4
2019-03-18 14:20:27 +08:00
#10 LinkedBlockingQueue
mccreefei
2019-03-18 17:39:09 +08:00
每个线程处理 1000 条,每过滤出 100 条有效数据封装一下塞到阻塞队列里,多余的数据加锁暂时存放到 list 中,消费者线程从阻塞队列里 100 条、100 条地拿数据写 excel,利用 countDownLatch,最后一个生产者线程处理那个 list ( list 中每 100 条塞阻塞队列)。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/545666

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX