gpt4 book ai didi

java - 如何有效地同步对目录的访问以最大化并发性

转载 作者:行者123 更新时间:2023-12-01 11:11:06 24 4
gpt4 key购买 nike

假设我们有一个客户端/服务器应用程序。客户端将目录发送到服务器,服务器将存储它。

客户端与服务器通信的协议(protocol)如下。

  1. 发送 clientId。 [说客户端1]

  2. 发送目录的元数据。

  3. 发送目录。 [/tmp/client1]

服务器执行以下操作作为响应。

  1. 验证 clientId。

  2. 分析客户端目录的元数据。

  3. 将文件存储在 [/tmp/server/client1]。

通常我们希望服务器是多线程的,以便它可以一次为多个客户端提供服务。对于每个客户端,都会生成一个新线程来处理它。

这是从客户端读取目录的服务器代码的一部分。

public DirServer readDir() throws IOException, ClassNotFoundException {
DirClient clientDir = (DirClient) objectInputStream.readObject();
String serverDirPath = "/tmp/server"
+ "/" + clientId;

List<FileServer> serverFiles = new ArrayList<>();
DirServer dirServer = null;

synchronized (lockObject) {
FileUtils.deleteDirectory(new File(serverDirPath));
Path pathToDir = Paths.get(serverDirPath);
Files.createDirectories(pathToDir.getParent());

for (int i = 0; i < clientDir.getNumberOfFiles(); i++) {
serverFiles.add(readFile());
}
dirServer = new dirServer(clientDir.getFullPath(), serverDirPath, serverFiles);
}

return dirServer;
}

假设我们现在线程池中有两个线程为客户端服务。

案例1:

线程 1:client1

线程 2:客户端 1

即来自不同计算机的 client1 的两个实例尝试联系服务器。对于这种情况,需要同步访问代码块,因为它们访问相同的路径/tmp/server/client1。

案例2:

线程 1:client1

线程 2:client2

对于这种情况,不同步访问代码块的效率要高得多。由于两个线程处理不同的路径/tmp/server/client1 和/tmp/server/client2。

应该如何实现这种条件同步?即仅当您访问同一目录时才同步,否则不同步。

请注意,执行synchronized(clientDir) 不起作用,因为该对象是通过网络读取的。因此,尽管两个 clientDir 在逻辑上可能相同,但它们实际上是两个不同的引用。

您可以假设您可以执行 clientDir.getClientId() 来获取客户端的 Id。

最佳答案

因为您需要在“逻辑clientDir”上同步。
您可以使用 clientDir 作为 key 从 HashMap 中获取虚拟对象,并在其上进行同步。

写入 hashmap 应该同步,但读取不应该同步。并且写入量不能超过“逻辑客户端目录”的数量。

==编辑==
读取返回现有虚拟对象是可以的(因为它们的行为类似于final),不需要同步。
返回 null 的读取将需要在同步内重新读取和(可能)写入。

关于java - 如何有效地同步对目录的访问以最大化并发性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32365910/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com