【发布时间】:2017-07-18 14:25:03
【问题描述】:
我在 Java 中遇到了这个问题。 我有一个名为 MyServer 的服务器类,我想实现一个线程池,其中每个线程在请求到来时运行 MyServer 的方法。我创建了另一个实现名为 MultiThreadedSocketServer 的服务器池的类。类是这样的:
public class MultiThreadedSocketServer {
public void startServer(MyServer s, int localport, int threadPoolSize) {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(threadPoolSize);
Runnable serverTask = new Runnable() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(localport);
System.out.println("Waiting for clients to connect...");
while (true) {
Socket clientSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket, s));
}
} catch (IOException e) {
System.err.println("Unable to process client request");
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
}
名为 MultiThreadedSocketServer 的类有一个名为 Server 的参数,该参数将其传递给创建线程的客户端 Task 类。客户端任务类是这样的:
class ClientTask implements Runnable {
private final Socket clientSocket;
private MyServer s;
public ClientTask(Socket clientSocket, MyServer s) {
this.s = s;
this.clientSocket = clientSocket;
}
@Override
public void run() {
System.out.println("Got a client !");
String inputLine = null;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Do whatever required to process the client's request
inputLine = in.readLine();
if (inputLine.equals("Bye")) {
System.out.println("Bye");
System.exit(0);
}
s.handleRequest(inputLine);
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
正如您所见,当请求到来时,MyServer 类的 handleRequest 方法被调用。我想让这个方法同步运行,这意味着一次只有一个线程能够运行这个方法。在方法实现之前添加同步不会实现任何目标。
谁能给我正确的方法来做到这一点? 提前感谢您的宝贵时间。
PS:我添加了整个代码
MyServer 类 http://pastebin.com/6i2bn5jj
多线程服务器类 http://pastebin.com/hzfLJbCS
正如在 main 中很明显,我创建了三个带有参数 Task、task2 和 Bye 的 handleRequest 请求。
正确的输出应该是
Waiting for clients to connect...
Got a client !
This is an input Task
Request for Task
Got a client !
This is an input task2
Request for task2
Got a client !
This is an input
Bye
但是顺序是混合的。有时可以先执行关闭服务器的 Bye。我想确保订单是主要创建请求的订单。
【问题讨论】:
-
使
MyServer.HandleReq()同步将防止多个线程同时在同一个MyServer实例上调用该方法。您有多少个 MyServer 实例?旁注:请尊重命名约定。 -
只有一个 MyServer 实例将始终运行。抱歉,如果您想澄清,我不知道命名约定,我将编辑我的帖子
-
方法以小写字母开头。 HandleReq 应该是handleReq,或者更好的是handleRequest。变量也一样。 ThreadPoolSize 应该是 threadPoolSize。如果您有一个 MyServer 实例,那么同步该方法就可以了。你如何测试它没有正确同步?
-
在 handleRequest 方法中,我使用反射根据输入字符串调用 MyServer 类的不同方法。即使将此方法声明为同步,我在每次执行时都会得到不同的结果。调用的方法并不总是以正确的顺序调用,即输入到达服务器端口的顺序。
-
同步并不能保证任何排序。我认为您是根据不正确的假设得出结论。如果您需要解释,您需要发布相关代码、示例输入和输出,并解释您希望代码做什么以及它会做什么。
标签: java multithreading concurrency server threadpool