我必须用java实现一个客户机-服务器应用程序,根据客户端文件的变化自动更新服务器目录中的txt文件,以完成家庭作业(必须这样做,因为我已经过了最后期限)。
我有一个包可以正确地处理文件中的更改,但是我对如何处理多个文件中的更改感到困惑。我的方法是对客户机目录中的每个文件使用单独的线程,并出于同样的原因在服务器目录中使用相应的线程。这种方法适用于单个文件,但不适用于多个文件。
下面的代码位于客户端,调用文件线程的checkfilestate方法来处理更新。
while(true){
for (Map.Entry<String, SynchronisedFile> entry : fileList.entrySet()) {
try {
System.err.println("SyncTest: calling fromFile.CheckFileState()");
sstt.start();
entry.getValue().CheckFileState();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
} catch (InterruptedException e) {
e.printStackTrace();
System.exit(-1);
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
System.exit(-1);
}
}
在服务器端,如果我使用以下命令启动单个线程:
Thread sstt = new Thread(new SyncThreadServer(sfileList.entrySet().iterator().next().getValue(),clientSocket));
sstt.start();
它按预期工作。但是如果我同时启动服务器端线程(其中包含从输入流解码json消息的方法),使用:
for (Map.Entry<String, SynchronisedFile> entry : sfileList.entrySet())
{
Thread sstt = new Thread(new SyncThreadServer(entry.getValue(),clientSocket));
sstt.setName(entry.getKey());
}
其他文件的线程开始从输入流中读取用于其他线程的json消息。我希望能够阻止服务器端循环启动下一个线程,至少在一个文件/线程的checkfile方法完成之前是这样。但我仍然可能会遇到问题后,最初的阶段,当所有的踏板运行在同一时间。在这种情况下,如何处理多线程有什么解决方案吗(所有线程都使用一个套接字)。
编辑:据我所知,这与同步有关。服务器上其他文件的线程正在访问输入流,而第一个线程甚至还没有处理完它的输入。下面是服务器线程的代码。我需要在第一个线程使用完输入流之前,以某种方式阻止其他线程访问它。任何帮助都将不胜感激。谢谢。
public class SyncThreadServer implements Runnable {
SynchronisedFile toFile; // this would be on the Server //Is an instance of the syncfile class, should be able to proc insts
Socket clientSocket;
public SyncThreadServer(SynchronisedFile tf, Socket aClientSocket){
toFile=tf;
clientSocket = aClientSocket;
}
@Override
public void run() {
Instruction inst = null;
InstructionFactory instFact=new InstructionFactory();
while(true){
{
try{
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
String smsg = in.readUTF();
Instruction receivedInst = instFact.FromJSON(smsg);
System.err.println(smsg);
// The Server processes the instruction
toFile.ProcessInstruction(receivedInst);
//if(receivedInst.Type().equals("EndUpdate")){
// out.writeUTF("NEXT"); //TODO: Change to Json
// out.flush();}
//else
//{
out.writeUTF("GO"); //TODO: Change to Json
out.flush();
}
//}
catch (IOException e) {
e.printStackTrace();
System.exit(-1); // just die at the first sign of trouble
} catch (BlockUnavailableException e) {
// The server does not have the bytes referred to by the block hash.
try {
DataOutputStream out2 = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream in2 = new DataInputStream(clientSocket.getInputStream());
out2.writeUTF("NGO"); //TODO: Change to Json
out2.flush();
String msg2 = in2.readUTF();
Instruction receivedInst2 = instFact.FromJSON(msg2);
toFile.ProcessInstruction(receivedInst2);
if(receivedInst2.Type().equals("EndUpdate")){
out2.writeUTF("NEXT"); //TODO: Change to Json
out2.flush();}
else
{
out2.writeUTF("GO"); //TODO: Change to Json
out2.flush();
}
} catch (IOException e1) {
e1.printStackTrace();
System.exit(-1);
} catch (BlockUnavailableException e1) {
assert(false); // a NewBlockInstruction can never throw this exception
}
}
// } //And here
}
}
}
暂无答案!
目前还没有任何答案,快来回答吧!