MST

星途 面试题库

面试题:Java文件目录管理类在多线程环境下的资源竞争问题及解决方案

在多线程环境中,多个线程同时对同一个文件目录进行操作(如创建文件、删除文件等),可能会出现资源竞争问题。请描述可能出现的问题场景,以及如何利用Java文件目录管理类结合线程同步机制(如锁机制等)来解决这些问题,给出代码示例及详细说明。
45.8万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

可能出现的问题场景

  1. 文件创建冲突:多个线程同时尝试在同一目录下创建同名文件,可能导致部分线程创建失败,或者创建出不完整的文件。
  2. 文件删除问题:一个线程准备删除某个文件时,另一个线程可能正在读取或写入该文件,这可能导致数据丢失或读取错误。同时,多个线程尝试删除同一文件,可能出现重复删除或部分删除的情况。
  3. 目录遍历混乱:在遍历目录时,一个线程可能正在添加或删除目录项,而另一个线程正在遍历,这会导致遍历结果不准确或引发异常。

解决方案及代码示例

  1. 使用 synchronized 关键字
import java.io.File;

public class DirectoryManager {
    private static final Object lock = new Object();

    public static void createFile(String filePath) {
        synchronized (lock) {
            File file = new File(filePath);
            try {
                if (file.createNewFile()) {
                    System.out.println("File created: " + file.getName());
                } else {
                    System.out.println("File already exists: " + file.getName());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void deleteFile(String filePath) {
        synchronized (lock) {
            File file = new File(filePath);
            if (file.exists()) {
                if (file.delete()) {
                    System.out.println("File deleted: " + file.getName());
                } else {
                    System.out.println("Failed to delete file: " + file.getName());
                }
            } else {
                System.out.println("File does not exist: " + file.getName());
            }
        }
    }
}
  1. 使用 ReentrantLock
import java.io.File;
import java.util.concurrent.locks.ReentrantLock;

public class DirectoryManagerWithReentrantLock {
    private static final ReentrantLock lock = new ReentrantLock();

    public static void createFile(String filePath) {
        lock.lock();
        try {
            File file = new File(filePath);
            if (file.createNewFile()) {
                System.out.println("File created: " + file.getName());
            } else {
                System.out.println("File already exists: " + file.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void deleteFile(String filePath) {
        lock.lock();
        try {
            File file = new File(filePath);
            if (file.exists()) {
                if (file.delete()) {
                    System.out.println("File deleted: " + file.getName());
                } else {
                    System.out.println("Failed to delete file: " + file.getName());
                }
            } else {
                System.out.println("File does not exist: " + file.getName());
            }
        } finally {
            lock.unlock();
        }
    }
}

代码说明

  1. synchronized 实现
    • 定义了一个静态的 Object 作为锁对象 lock
    • createFiledeleteFile 方法中,使用 synchronized 块包裹文件操作代码。这确保了同一时间只有一个线程能够执行这些文件操作,避免资源竞争。
  2. ReentrantLock 实现
    • 创建了一个静态的 ReentrantLock 对象 lock
    • createFiledeleteFile 方法中,首先调用 lock.lock() 获取锁,确保只有一个线程能进入临界区执行文件操作。
    • 使用 try - finally 块,在 finally 中调用 lock.unlock() 释放锁,保证无论操作是否成功,锁都会被释放,避免死锁。