- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这里需要线程专家的眼睛......
我在一个 poc 应用程序上,我正在 FTP 服务器上上传文件
在FTP 服务器上有多个文件夹。根据输入响应,我从文件夹中读取文件并移动到另一个文件夹
该应用程序可以同时被多个线程访问。
所以问题是这样的:
假设 FTP 有一个文件夹 Folder_A 和 A_A_FOLDER现在 Folder_A 有 10 个文件。一个线程来了,从 FTP 读取了 10 个文件并开始对其进行一些计算,它一一计算,然后移动到 A_A_FOLDER它在过程中(假设它成功地将 5 个文件从 Folder_A 移动到 A_A_FOLDER)然后另一个线程来了,它选择了剩余的 5 个文件,因为它们被线程 1 处理不足,所以线程 2 也开始处理这 5 个文件
这里有重复文件问题
void m1(String folderName) {
// FTP related code
}
我已经通过使用synchronized关键字解决了这个问题
现在一切都同步了,所有的处理工作都正常
synchronized void m1(String folderName) {
// code
}
folderName决定处理哪个文件夹
现在我开始面临性能问题
因为该方法是同步的,所以所有线程都将等待,直到处理线程未完成其任务。
我可以通过以下步骤改进它:
(在解决这个问题之前,有一些故事可以深入挖掘这个问题)
正如我提到的 m1 方法的 folderName 参数决定处理哪个文件夹,所以假设我在 Ftp 服务器中有 4 个文件夹(A、B、A_T、B_T),其中 2 个文件夹是需要从中读取数据的文件夹(A 和 B),2 个文件夹是数据将移动的地方(A_T 和 B_T)
A_T 和 B_T 不是这里的关注点,因为它们对于每个文件夹 A 和 B 都是唯一的因此,如果该方法将从 A 读取,那么它将把它移动到 A_T 与 B 相同(移动到 B_T)
现在:
假设 m1 方法有 4 个线程,文件夹 A 有 3 个线程,文件夹 B 有 1 个如果以某种方式基于 fileName 参数同步请求以便我可以提高性能,这意味着 1 个线程将在 A 上工作,另外 2 个线程将阻塞,因为 fileName 对它们来说是相同的,所以它们将等到第一个线程未完成任务,线程 4 将并行无需任何锁定过程即可工作,因为它的文件名不同
那么我怎样才能在代码级别实现这个(在文件名上同步)呢?
注意:我知道我可以使用资源的静态锁定列表然后锁定文件名资源来打破这个逻辑例如:
private final Object A = new Object();
private final Object B = new Object();
但这种方法的问题是文件夹可以动态添加,所以我不能这样做。
需要你们的帮助。
最佳答案
一种方法是为每个目录维护一个锁:
public class DirectoryTaskManager {
public static void main(String[] args) throws IOException {
DirectoryTaskManager manager = new DirectoryTaskManager();
manager.withDirLock(new File("Folder_A"), () -> System.out.println("Doing something..."));
}
public void withDirLock(File dir, Runnable task) throws IOException {
ReentrantLock lock = getDirLock(dir);
lock.lock();
try {
task.run();
} finally {
lock.unlock();
}
}
private Map<File, ReentrantLock> dirLocks = Collections.synchronizedMap(new HashMap<>());
public ReentrantLock getDirLock(File dir) throws IOException {
// Resolve the canonical file here so that different paths
// to the same file use the same lock
File canonicalDir = dir.getCanonicalFile();
if (!canonicalDir.exists() || !canonicalDir.isDirectory()) {
throw new FileNotFoundException(canonicalDir.getName());
}
return dirLocks.computeIfAbsent(canonicalDir, d -> new ReentrantLock());
}
}
关于java - 多线程 : Dynamically object locking based on resource in hava,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49498139/
这里需要线程专家的眼睛...... 我在一个 poc 应用程序上,我正在 FTP 服务器上上传文件 在FTP 服务器上有多个文件夹。根据输入响应,我从文件夹中读取文件并移动到另一个文件夹 该应用程序可
我是一名优秀的程序员,十分优秀!