filelock不能防止多java进程同时写同一文件,因其为建议性锁,需所有进程主动调用lock()并检查返回值才生效;绕过锁直接写文件将导致互斥失效,跨jvm同步须依赖外部协调机制。

Java 多线程环境下安全读写同一文件,核心是区分“进程内线程同步”和“跨进程文件同步”两种场景——前者用 JVM 层锁(如 synchronized、ReentrantLock)即可;后者必须依赖操作系统级的 FileLock,否则多进程会绕过 JVM 锁导致冲突。
用 FileLock 实现跨进程安全写入
这是最可靠的方式,底层调用 OS 文件锁,支持多 JVM 进程互斥:
- 用
RandomAccessFile("file.txt", "rw")打开文件,获取FileChannel - 写操作前调用
channel.lock()(阻塞式)或channel.tryLock()(非阻塞),返回FileLock对象 - 加锁成功后,再用
FileOutputStream或FileChannel.write()写入数据 -
必须在
finally块中显式调用lock.release()和channel.close(),否则锁可能残留
读写分离时用 ReadWriteLock 提升并发度
若文件读多写少(如配置文件),可用 ReentrantReadWriteLock 避免读操作互相阻塞:
- 读线程获取
readLock().lock():允许多个线程同时读 - 写线程获取
writeLock().lock():独占,会阻塞所有读/写线程 - 注意:
ReadWriteLock只对同一 JVM 内线程有效,不解决多进程问题
避免锁竞争的实用策略
频繁小量写入时,加锁本身成瓶颈,可改用缓冲+批量落盘:
- 各线程将待写内容暂存到线程安全队列(如
ConcurrentLinkedQueue) - 单个守护线程定期从队列取数据,加一次锁完成批量写入
- 减少锁持有时间,显著提升吞吐量,适合日志、监控等场景
关键细节不能忽略
很多问题出在细节处理上:
-
FileLock是建议性锁(advisory),需所有参与者主动检查,OS 不强制拦截非法访问 - 不要混用
FileOutputStream和FileChannel操作同一文件,可能引发IOException - Windows 下
FileLock作用于整个文件;Linux 支持区域锁,但需明确指定偏移和长度 - JVM 异常退出时,锁可能未释放,建议配合
Runtime.addShutdownHook()做兜底清理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











