带有内部类和最终变量的线程化Java服务器
我编写了以下代码来实现线程服务器:带有内部类和最终变量的线程化Java服务器,java,sockets,final,anonymous-inner-class,Java,Sockets,Final,Anonymous Inner Class,我编写了以下代码来实现线程服务器: ServerSocket passiveSocket = new ServerSocket(port, maxConnections); while(true){ final Socket socket = passiveSocket.accept(); new Thread(new Runnable() { public void run() { //access so
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();
}
现在这似乎是可行的,但在反思中,我并不真正理解下一个连接到达时,最终的套接字变量socket发生了什么。每个线程如何与启动线程时的当前套接字实例关联?-最后一个关键字对此负责吗?这样想:
socket
被秘密地作为参数传递给新的Runnable
构造函数,并作为变量保存在匿名Runnable
类中。(在字节码级别,它实际上就是这样工作的。)
创建的
Runnable
对象在创建时包含对一个特定Socket
值的引用,因此它可以在创建完成后关闭该特定Socket。将final
变量传递给匿名内部类时,该变量有效地存储在匿名类中,就像它是一个实例变量一样
上述代码可以有效地转换为:
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();
}
}
请注意,使局部变量成为final是在匿名内部类中访问它的唯一方法。有关原因的详细信息,请参见“”