从多个线程写入文本文件?

我有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。