简体   繁体   English

具有内部类和最终变量的线程Java服务器

[英]Threaded Java server with inner class and final variable

I've written the following code to implement a Threaded Server: 我编写了以下代码来实现线程服务器:

ServerSocket passiveSocket = new ServerSocket(port, maxConnections);  
while(true){
  final Socket socket = passiveSocket.accept();                       
  new Thread(new Runnable() {
      public void run() {
          //access socket as needed to communicate. E.g.:
          PrintWriter writer = new PrintWriter(socket.getOutputStream());
          //Finally close socket.
          socket.close();
      }
  }).start();
}

Now this seems to work, but in reflection I do not really understand what's going on with the final socket variable socket when the next connection arrives. 现在,这似乎可行,但是从反思来看 ,当下一个连接到达时,最终套接字变量socket到底是怎么回事。 How is each thread associated with the socket instance which was current when starting the thread? 启动线程时,每个线程如何与当前的套接字实例关联? - is the final keyword responsible for that? - 最终关键字对此负责吗?

Think of it this way: socket is secretly passed as an argument to the new Runnable constructor, and it's kept as a variable in the anonymous Runnable class. 这样想:将socket作为参数秘密传递给new Runnable构造函数,并将其作为变量保留在匿名Runnable类中。 (That's actually how it works, at the bytecode level.) (这实际上是在字节码级别上的工作方式。)

The created Runnable object contains a reference to the one specific Socket value at its creation time, so it can close that specific socket when it's done. 创建的Runnable对象在创建时包含对一个特定Socket值的引用,因此完成后可以关闭该特定的套接字。

When passing a final variable to an anonymous inner class, that variable is effectively stored in the anonymous class as if it was an instance variable. 当将final变量传递给匿名内部类时,该变量将有效地存储在匿名类中,就好像它是实例变量一样。

The code above could be effectively translated to: 上面的代码可以有效地转换为:

private static final class RunnableAnonSubclass implements Runnable {
    private final Socket socket; 
    private RunnableAnonSubclass (Object socket) {
        this.socket = socket;
    }

    public void run() {
        //access socket as needed to communicate. E.g.:
        PrintWriter writer = new PrintWriter(socket.getOutputStream());
        //Finally close socket.
        socket.close();
    }
}

// ... 
{ 
    ServerSocket passiveSocket = new ServerSocket(port, maxConnections);  
    while(true){
        Socket socket = passiveSocket.accept();               
        new Thread(new RunnableAnonSubclass(socket)).start();
    }
}

Notice that making a local variable final is the only way to access it inside an anonymous inner class. 请注意,使局部变量为final是在匿名内部类中访问它的唯一方法。 See Jon's answer on " Why are only final variables accessible in anonymous class? " for details on the reasons. 有关原因的详细信息,请参见Jon关于“ 为什么只能在匿名类中访问最终变量?的答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM