Я создаю приложение для универа, которое эмулирует клиент-серверное программное обеспечение для отправки и получения электронной почты.Я хочу понять, правильно ли следующая реализация синхронизирует чтение и запись файлов на стороне сервера, кажется, что она работает правильно, но я не на 100% уверен, что это имеет смысл.Для каждого пользователя у меня есть файл полученных писем и файл отправленных писем.
Ситуация следующая, у меня есть N задач, каждая из которых управляется отдельным классом, точнее, у меня есть следующее:LoginTask, ReceiveTask, SendTask и DeleteTask коды очень похожи среди них, поэтому я не буду помещать все это.
Отправить задачу
public class SendTask extends Thread implements Runnable {
private final ServerModel model;
private final Socket incoming;
private final ObjectOutputStream out;
private final ObjectInputStream in;
public SendTask(Socket s, ServerModel model, ObjectOutputStream outObj, ObjectInputStream inObj) {
this.out = outObj;
this.in = inObj;
this.incoming = s;
this.model = model;
setDaemon(true);
}
.... some code ....
boolean validUsers = true;
for (String receiver : receiverToString) {
if (!model.checkUser(receiver)) {
out.writeObject("false");
validUsers = false;
break;
}
}
if(validUsers) {
model.writeSended(emailToString);
model.writeReceived(emailToString);
out.writeObject("confermo");
}
Удалить задачу
public class DeleteTask extends Thread implements Runnable {
private final ServerModel model;
private final Socket incoming;
private final ObjectOutputStream out;
private final ObjectInputStream in;
private final String user;
public DeleteTask(Socket s, ServerModel model, ObjectOutputStream outObj, ObjectInputStream inObj, String user) {
this.out = outObj;
this.in = inObj;
this.incoming = s;
this.model = model;
this.user = user;
setDaemon(true);
}
@Override
public void run() {
try {
String email = (String)in.readObject();
String fileType = (String)in.readObject();
String outcome = model.deleteEmail(email, user, fileType);
out.writeObject(outcome);
incoming.close();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(DeleteTask.class.getName()).log(Level.SEVERE, null, ex);
}
}
На стороне сервера у меня есть объект с именем model, который читает и записывает файлы, чтобы сохранять и загружать электронные письма. Каждый раз, когда я выполняю задачу, я передаю ссылку на этот объект, как этот, в классе ServerViewController:
case "send":
Runnable sendTask = new SendTask(incoming, serverModel, outObj, inObj);
exec.execute(sendTask);
break;
case "delete":
String userD = (String)inObj.readObject();
Runnable deleteTask = new DeleteTask(incoming, serverModel, outObj, inObj, userD);
exec.execute(deleteTask);
Наконец, в моем классе ServerModel (указанном объектом модели, переданным из контроллера в задачи) все сигнатуры, которые читаются или записываются в файл, объявляются синхронизированными:
public synchronized String deleteEmail(String mail, String user, String type) throws IOException {
public synchronized void writeReceived(String[] emailToString) throws IOException, ClassNotFoundException, InterruptedException {
public synchronized void writeSended(String[] emailToString) throws IOException {
public synchronized ArrayList<String> loadUserReceivedEmails(String username) throws IOException {
public synchronized ArrayList<String> loadUserSendedEmails(String username) throws IOException {
Я хочу знать, синхронизируются ли объекты модели между ними по определению, поскольку они являются одним и тем же объектом, или, если это не так, выполняет ли моя синхронизацияправильно ли работают?Достаточно ли объявить синхронизированные методы для правильного управления файлами?
Было бы лучше или более разумно опустить синхронизированные в сигнатурах и записать некоторые блоки в классы задач, как показано ниже
synchronized(model) { ... task do your things on the model ... }
???