gpt4 book ai didi

java - 使用多线程写入文件

转载 作者:搜寻专家 更新时间:2023-10-31 08:17:02 26 4
gpt4 key购买 nike

我正在尝试使用多线程在 Java 中编写一个大文件。

我已经在 J​​ava 中尝试了 FileWriterbufferedWriter 类。

正在写入的内容实际上是使用 CopyManager 读取并写入的整个表 (Postgres)。文件中的每一行都是表中的一个元组,我一次写了 100 行。

写法:

单个待写文件被多个线程以追加方式打开。此后每个线程都会尝试写入文件 file。

以下是我面临的问题:

  • 有时,文件的内容会被覆盖,即:一行未完成,下一行从那里开始。我在这里的假设是 writer 的缓冲区已满。这会强制编写器立即将数据写入文件。写入的数据可能不是完整的一行,在它可以写入剩余部分之前,下一个线程将其内容写入文件。
  • 在使用 Filewriter 时,有时我会在文件中看到一条黑线。

有什么建议,如何避免这种数据完整性问题?

最佳答案

共享资源==争用

根据定义,写入普通文件是一种序列化操作。尝试从多个线程写入它不会获得任何性能,I/O 是一种有限的有界资源,其带宽甚至比最慢或最过载的 CPU 少几个数量级。

对共享资源的并发访问可能很复杂(而且很慢)

如果您有多个线程在执行昂贵的计算,那么您有多种选择,如果您只是使用多个线程,因为您认为自己会加快速度,那么您只会做相反的事情。对 I/O 的争用总是会减慢对资源的访问,它永远不会因为锁等待和其他开销而加快访问速度。

您必须有一个 protected 关键部分,并且一次只允许一个写入者。只需查找任何支持并发的日志编写器的源代码,您就会发现只有一个线程写入文件。

如果您的应用主要是:

  1. CPU Bound:您可以使用某种锁定机制/数据构造,一次只让多个线程中的一个线程写入文件,从并发的角度来看,这将毫无用处,因为一个天真的解决方案;如果这些线程受 CPU 限制且 I/O 很少,这可能会起作用。

  2. I/O Bound:这是最常见的情况,您必须使用带有某种队列的消息传递系统,并将所有线程发送到队列/缓冲区,并且从中提取一个线程并写入文件。这将是最具扩展性和最容易实现的解决方案。

日记 - 异步写入

如果您需要创建单个超大文件,其中写入顺序不重要且程序受 CPU 限制,您可以使用日志记录技术。

让每个 process 写入一个单独的文件,然后在最后将多个文件连接成一个大文件。这是一个非常老派的低技术解决方案,效果很好并且已经使用了几十年。

显然,您拥有的存储 I/O 越多,它在结束连接时的性能就越好。

关于java - 使用多线程写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22308158/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com