【问题标题】:Java: Spawning a thread which accepts sockets when needed?Java:在需要时生成一个接受套接字的线程?
【发布时间】:2019-11-28 15:00:47
【问题描述】:

免责声明:我对 Java 还很陌生,所以这可能是一个愚蠢的问题。 我们开始吧。

我正在编写一个程序,它侦听端口、接受连接、执行其操作并关闭端口。

我希望它在它自己的线程中运行,该线程处理完整的通信。因此,ServerSocket.accept() 将在线程中启动。

但是我怎样才能只在需要时才生成线程呢?如果我还没有使用 ServerSocket.accept(),我不知道我是否收到了数据,但是如果我在 main 方法中这样做,我将无法在这个打开时接受一个新的。

为了清楚起见,一些示例代码省略了导入:

public class communicator implements Runnable{

       private ServerSocket server;
       private Socket socket;

       Thread t;

       communicator(ServerSocket server){
          this.server = server;

          t = new Thread(this,"MyThread");
          t.start();

       }

       public void run() {
           try {
               socket = server.accept();
               //do stuff
               socket.close();
           } catch (IOException ex) {
               Logger.getLogger(communicator.class.getName()).log(Level.SEVERE, null, ex);
           }
       }
}

和主类:

public class test {
    private static ServerSocket server;
    private static Socket socket;

    public static void main(String[] args) throws IOException{
        server = new ServerSocket(123);
        communicator comm = new communicator(server);
    }
}

或者我可以使用类似“如果一个线程处于活动状态,则提供一个新线程”之类的东西?

谢谢。

【问题讨论】:

  • 这能回答你的问题吗? Creating the ServerSocket in a separate thread?
  • 我不明白这个问题。如果您在需要时生成一个接受套接字的线程,您将不会在主线程中调用accept(),因此您不会遇到您描述的问题,因此您已经有了解决方案。那么你的问题是什么?
  • 我有一个接受连接的线程。虽然这是开放的,但我可以获得另一个请求,但如果没有其他线程可以接受它,则无法接受。所以我需要另一个线程,但我不知道是否有另一个请求,所以我总是需要提供一个免费线程,但由于我不知道会有多少连接,我需要有很多线程准备好了,以防万一。

标签: java multithreading sockets


【解决方案1】:

您可以使用类似这样的线程池和 ExecturonerService。


public class Listener implements Runnable {

    private ServerSocket serverSocket;
    ExecutorService executorService = Executors.newCachedThreadPool();

    public Listener(ServerSocket serverSocket) {
        this.serverSocket = serverSocket;
    }

    @Override
    public void run() {
        try {
            while (true) {
                Socket accept = serverSocket.accept();
                executorService.execute(new Worker(accept));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

Listener 等待连接到来,创建一个新的 Worker 对象并给它执行者服务来运行它。此服务将处理您需要的线程数,并在任务完成后清理所有内容。

public class Worker implements Runnable{

    private Socket socket;

    public Worker(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        //do stuff
    }
}

【讨论】:

  • 那么,有可能在另一个已经处于活动状态的情况下接受(在 while 循环中)吗?那当然可以解决。这似乎在没有手动显式设置线程的情况下运行?那很好。我试试看。
  • 有点小错误,ServerListener应该是构造函数,所以叫Listener :) 这个很好用,谢谢!
  • 是的。另一个线程中的所有内容都不会受到接受的影响。您可以同时打开任意数量的线程。我建议您阅读一些有关线程池及其工作原理的教程。例如link
  • 太好了,谢谢!
猜你喜欢
  • 2012-04-01
  • 1970-01-01
  • 2013-09-08
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
  • 2012-05-17
相关资源
最近更新 更多