从多个线程写入文本文件?
我有20个线程用println()函数写入一个名为results.txt的文件。 我如何同步它们?
我注意到每次运行程序时,我在results.txt中都有不同数量的文本行。
谢谢。
通过包含要写入文件的synchronized方法的类访问该文件。 一次只能有一个线程执行该方法。
我认为Singleton模式适合您的问题:
package com.test.singleton; public class Singleton { private static final Singleton inst= new Singleton(); private Singleton() { super(); } public synchronized void writeToFile(String str) { // Do whatever } public Singleton getInstance() { return inst; } }
每次需要写入文件时,您只需要拨打:
Singleton.getInstance().writeToFile("Hello!!");
重复的问题……重复的答案。 正如我在这里所说:
如果您可以将文件保存为FileOutputStream
,则可以将其锁定为:
FileOutputStream file = ... .... // Thread safe version. void write(byte[] bytes) { try { boolean written = false; do { try { // Lock it! FileLock lock = file.getChannel().lock(); try { // Write the bytes. file.write(bytes); written = true; } finally { // Release the lock. lock.release(); } } catch ( OverlappingFileLockException ofle ) { try { // Wait a bit Thread.sleep(0); } catch (InterruptedException ex) { throw new InterruptedIOException ("Interrupted waiting for a file lock."); } } } while (!written); } catch (IOException ex) { log.warn("Failed to lock " + fileName, ex); } }
您打算将数据写入一个文件。 因此,如果您尝试锁定整个文件,最好使用单个线程来完成这项工作。 虽然你产生了20个线程,但是每次调用方法时只有一个线程正在运行,其他线程只是在等待锁定。
我建议您使用RandomAccessFile
将数据写入您的文件。 然后每个线程可以将一些唯一数据写入文件而不锁定整个文件。
一些演示代码如下
try { final RandomAccessFile file = new RandomAccessFile("/path/to/your/result.txt", "rw"); final int numberOfThread = 20; final int bufferSize = 512; ExecutorService pool = Executors.newFixedThreadPool(numberOfThread); final AtomicInteger byteCounter = new AtomicInteger(0); final byte[] yourText = "Your data".getBytes(); for (int i = 0; i < yourText.length; i++) { pool.submit(new Runnable() { @Override public void run() { int start = byteCounter.getAndAdd(bufferSize); int chunkSize = bufferSize; if (start + bufferSize > yourText.length) { chunkSize = yourText.length - start; } byte[] chunkData = new byte[chunkSize]; System.arraycopy(yourText, start, chunkData, 0, chunkSize); try { file.write(chunkData); } catch (IOException e) { //exception handle } } }); } file.close(); } catch (Exception e) { //clean up }
使用记录框架,例如已经整理好所有内容的logback。