You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java多线程操作文件异常:文件创建后无法写入且程序挂起

线程操作文件挂起且写入线程未执行的原因及修复

问题场景

用两个线程操作同一文件时,负责创建文件的Thread1执行完成,但写入内容的Thread2未执行写入操作,程序挂起无法正常退出。

程序输出

File created: example.txt
Thread 1: File creation finished

完整代码

import java.io.*;

public class ThreadWithFiles {
    private static final String FILE_PATH = "/Users/myUser/Desktop/example.txt";

    public static void main(String[] args) {

        Object lock = new Object();

        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                createFile();
                System.out.println("Thread 1: File creation finished");
                lock.notify();
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                try {
                    lock.wait();
                    populateFile();
                    lock.notify();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // Start both threads
        thread1.start();
        thread2.start();

        try {

            synchronized (lock) {
                thread2.join();
                lock.wait();
                System.out.println("Main thread: Both actions terminated successfully");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void createFile() {
        try {
            File file = new File(FILE_PATH);
            if (file.createNewFile()) {
                String[] words = FILE_PATH.split("/");
                String fileName = words[words.length - 1];
                System.out.println("File created: " + fileName);
            } else {
                System.out.println("File already exists: " + FILE_PATH);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void populateFile() {
        try (FileWriter writer = new FileWriter(FILE_PATH, true)) {
            writer.write("Hello, this is some text to populate the file.");
            System.out.println("File populated with text");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

原因分析

1. 主线程抢占锁导致Thread2无法执行

主线程在synchronized(lock)代码块内调用thread2.join(),此时主线程持有lock锁,而Thread2必须先获取lock锁才能执行wait()等待唤醒。Thread1执行完notify()释放锁后,主线程大概率先抢到锁,然后卡在thread2.join()等待Thread2结束,但Thread2因为拿不到锁根本无法启动执行,形成循环等待,程序挂起。

2. 主线程多余的wait()调用

主线程在thread2.join()后调用lock.wait(),此时没有其他线程会去唤醒主线程,导致主线程永久阻塞,程序无法退出。

修复方案

调整主线程的等待逻辑,移除不必要的同步锁和wait()调用,让Thread2能正常获取锁并执行:

import java.io.*;

public class ThreadWithFiles {
    private static final String FILE_PATH = "/Users/myUser/Desktop/example.txt";

    public static void main(String[] args) {

        Object lock = new Object();

        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                createFile();
                System.out.println("Thread 1: File creation finished");
                lock.notify();
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                try {
                    lock.wait();
                    populateFile();
                    System.out.println("Thread 2: File population finished");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // Start both threads
        thread1.start();
        thread2.start();

        try {
            // 直接等待两个线程执行结束,无需持有锁
            thread1.join();
            thread2.join();
            System.out.println("Main thread: Both actions terminated successfully");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void createFile() {
        try {
            File file = new File(FILE_PATH);
            if (file.createNewFile()) {
                String[] words = FILE_PATH.split("/");
                String fileName = words[words.length - 1];
                System.out.println("File created: " + fileName);
            } else {
                System.out.println("File already exists: " + FILE_PATH);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void populateFile() {
        try (FileWriter writer = new FileWriter(FILE_PATH, true)) {
            writer.write("Hello, this is some text to populate the file.");
            System.out.println("File populated with text");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

修复要点

  • 把thread1.join()和thread2.join()移出synchronized(lock)代码块,避免主线程抢占Thread2需要的锁。
  • 移除主线程中多余的lock.wait()调用,线程执行完成后直接输出结果即可。
  • Thread2执行完毕后无需调用lock.notify(),因为没有其他线程等待该锁的通知。

内容的提问来源于stack exchange,提问作者user2418888

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:12:19