java-simple中的多线程

java-simple中的多线程,java,multithreading,network-programming,Java,Multithreading,Network Programming,我有一个简单的问题,如何将这个服务器转换成多线程,因为现在它只处理一个客户机。哪个部分应该进入run()部分:) listener.accept()之后的部分。一旦主线程接收到来自客户机的连接,就让另一个线程(最好是池线程)处理与该客户机的通信,以便主线程可以接受另一个 使用a执行此操作:每次接受连接时,构造一个新的Runnable实例,并使其由执行器执行。侦听器.accept()后面的部分。一旦主线程接收到来自客户机的连接,就让另一个线程(最好是池线程)处理与该客户机的通信,以便主线程可以接受

我有一个简单的问题,如何将这个服务器转换成多线程,因为现在它只处理一个客户机。哪个部分应该进入run()部分:)


listener.accept()之后的部分。一旦主线程接收到来自客户机的连接,就让另一个线程(最好是池线程)处理与该客户机的通信,以便主线程可以接受另一个


使用a执行此操作:每次接受连接时,构造一个新的
Runnable
实例,并使其由执行器执行。

侦听器.accept()后面的部分。一旦主线程接收到来自客户机的连接,就让另一个线程(最好是池线程)处理与该客户机的通信,以便主线程可以接受另一个


使用a执行此操作:每次接受连接时,构造一个新的
Runnable
实例,并使其由执行器执行。

为从accept返回的每个连接提供服务时,应进入一个单独的线程,即应将以下内容移到
run()
方法中:

System.out.println(socket + " " + "welcome\n");
try {
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    out.println(new Date().toString());
    BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    String answer = input.readLine();
    System.out.println(answer);
    if ("hej".equals(answer)) {
        System.out.println("Sacrafice accepted");
    }
}
finally {
    socket.close();
}
当然,您需要添加创建线程的代码。由于线程创建是一项昂贵的任务,而且线程是可重用的,因此最好在初始化期间预先在池中创建多个工作线程,然后在接受连接并需要线程为其提供服务后,才从池中检索工作线程。在开发应用程序时,您可能会发现添加一些逻辑以根据负载在运行时调整线程池大小是一个好主意,但在当前阶段,您可能不应该这样做,只需使用配置项(如命令行选项或静态最终选项)来设置初始线程池大小。您可以在中找到线程池实现

如果您这样做,线程的
run()
方法将非常简单,它将在循环中等待新任务,并且每次收到任务时都应该运行该任务的
run()
方法。上面的代码应该放在任务的not线程的
run()
方法中。通过这种方式,您可以将线程与任务分开,从而确保线程保持可重用性。线程还需要一个方法来接收任务,并且该方法应该是线程安全的。您可以使用中的一个队列实现将任务存储在线程中,从任务进入线程进行服务到线程的
run()
方法将任务从队列中取出以实际运行任务


线程和任务的这种分离是添加另一个间接级别解决一个重要的软件工程问题时的另一种情况。

为从accept返回的每个连接提供服务时,应该进入一个单独的线程,即应将以下内容移到
run()
方法中:

System.out.println(socket + " " + "welcome\n");
try {
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    out.println(new Date().toString());
    BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    String answer = input.readLine();
    System.out.println(answer);
    if ("hej".equals(answer)) {
        System.out.println("Sacrafice accepted");
    }
}
finally {
    socket.close();
}
当然,您需要添加创建线程的代码。由于线程创建是一项昂贵的任务,而且线程是可重用的,因此最好在初始化期间预先在池中创建多个工作线程,然后在接受连接并需要线程为其提供服务后,才从池中检索工作线程。在开发应用程序时,您可能会发现添加一些逻辑以根据负载在运行时调整线程池大小是一个好主意,但在当前阶段,您可能不应该这样做,只需使用配置项(如命令行选项或静态最终选项)来设置初始线程池大小。您可以在中找到线程池实现

如果您这样做,线程的
run()
方法将非常简单,它将在循环中等待新任务,并且每次收到任务时都应该运行该任务的
run()
方法。上面的代码应该放在任务的not线程的
run()
方法中。通过这种方式,您可以将线程与任务分开,从而确保线程保持可重用性。线程还需要一个方法来接收任务,并且该方法应该是线程安全的。您可以使用中的一个队列实现将任务存储在线程中,从任务进入线程进行服务到线程的
run()
方法将任务从队列中取出以实际运行任务


线程和任务的这种分离是添加另一层间接寻址解决一个重要的软件工程问题时的又一种情况。

创建一个类serverThread,继承自Thread,以声明一个构造函数,该构造函数在Run()方法中接受套接字复制整个try{}catch{}


google翻译了

创建一个类serverThread,继承自Thread,以声明一个构造函数,该构造函数在Run()方法中使用套接字复制整个try{}catch{}


每个客户端连接使用一个线程。 这种多客户端服务器中的基本逻辑流程如下:

while (true) {
    accept a connection ;
    get a thread from pool to deal with the client ;
}

每个客户端连接使用一个线程。 这种多客户端服务器中的基本逻辑流程如下:

while (true) {
    accept a connection ;
    get a thread from pool to deal with the client ;
}

比基于队列实现线程池更好的是,只需使用ExecutorService,它为您实现池和队列。没错。这只是一个设计大纲,和往常一样,检查现有的和经过验证的实现是否解决了您的问题是一个好主意。无论哪种方式,了解设计都有助于实现您自己的解决方案和有效地使用现有解决方案。感谢您添加对相关现有解决方案的提及。与基于队列实现线程池相比,只需使用ExecutorService,它可以为您实现池和队列。没错。这只是一个设计大纲,和往常一样,检查现有的和经过验证的实现是否解决了您的问题是一个好主意。无论哪种方式,了解设计都有助于实现您自己的解决方案和有效地使用现有解决方案。感谢您添加对相关现有解决方案的提及。您是否应该继承