gpt4 book ai didi

java - Java多线程阻止两个函数同时运行

转载 作者:行者123 更新时间:2023-12-03 12:52:05 25 4
gpt4 key购买 nike

我正在创建一个多线程服务器,并且创建了一个用于管理用户的类,但是我注意到,当一个线程正在读取文件而另一个线程正在写入文件时,我的UserManager类可能会导致错误,如何防止呢?

package server.questiongiver;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;

import server.engine.CustomLog;

public class UserManager {

public static User loadUser(String id, Socket s) {
User user = null;
if (id == null) {
return user;
}
File f = new File("users.dat");
if (f.isFile() && f.canRead()) {
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
String line;
while ((line = br.readLine()) != null) {
if (line.equals("[" + id + "]")) {
user = new User(s);
user.id = id;
user.password = br.readLine().split("-separator-")[1];
user.username = br.readLine().split("-separator-")[1];
break;
}
}
}
catch (IOException ex) {
CustomLog.error(ex.getMessage());
}
}
return user;
}

public static ArrayList<User> loadAllUsers() {
File f = new File("users.dat");
ArrayList<User> users = new ArrayList();
if (f.isFile() && f.canRead()) {
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
String line;
while ((line = br.readLine()) != null) {
if (line.matches("^(\\[[0-9]*\\])$")) {
User user = new User(null);
user.id = line.replace("[", "").replace("]", "");
user.password = br.readLine().split("-separator-")[1];
user.username = br.readLine().split("-separator-")[1];
users.add(user);
}
}
}
catch (IOException ex) {
CustomLog.error(ex.getMessage());
}
}
return users;
}

public static void saveUser(User user) {
File f = new File("users.dat");
String content = "";
String newLine = System.getProperty("line.separator");
boolean found = false;
if (f.isFile() && f.canRead()) {
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
String line;
while ((line = br.readLine()) != null) {
if (line.equals("[" + user.id + "]") && br.readLine().equals(user.password)) {
found = true;
content += "[" + user.id + "]" + newLine;
content += "password-separator-" + user.password + newLine;
content += "username-separator-" + user.username + newLine;
br.readLine();
}
else {
content += line + newLine;
}
}
}
catch (IOException ex) {
CustomLog.error(ex.getMessage());
}
}
if (!found) {
content += "[" + user.id + "]" + newLine;
content += "password-separator-" + user.password + newLine;
content += "username-separator-" + user.username + newLine;
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(f))) {
writer.write(content);
writer.close();
}
catch (FileNotFoundException | UnsupportedEncodingException ex) {
CustomLog.error(ex.getMessage());
}
catch (IOException ex) {
CustomLog.error(ex.getMessage());
}
}
}

最佳答案

您可以将UserManager中的所有方法声明为synchronized。这将防止方法被多个线程同时执行。

但是,更好的解决方案是使用 ReadWriteLock ,其中load不透明度使用ReadLock,而save操作使用WriteLock。读锁可以同时由多个线程获取,而写锁则授予对一个线程的独占访问权限。

关于java - Java多线程阻止两个函数同时运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31499762/

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