The following code snippet is from listing 6.2 in Java Concurrency in Practice (http://jcip.net/listings/ThreadPerTaskWebServer.java)
package net.jcip.examples;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* ThreadPerTaskWebServer
* <p/>
* Web server that starts a new thread for each request
*
* @author Brian Goetz and Tim Peierls
*/
public class ThreadPerTaskWebServer {
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(80);
while (true) {
final Socket connection = socket.accept();
Runnable task = new Runnable() {
public void run() {
handleRequest(connection);
}
};
new Thread(task).start();
}
}
private static void handleRequest(Socket connection) {
// request-handling logic here
}
}
In the book, the final
keyword is bolded, as if to highlight its importance. In previous chapters (especially chapter 3), final
is discussed in regards to thread-safe publication. However, in this example the final
keyword seems to be important for different reasons, essentially because of Java's "closure" behavior - Why are only final variables accessible in anonymous class?
Am I right that the final
keyword is purely for that purpose, and safe-publication has nothing to do with its usage here?
You are right. And from Java 8 onwards, you can leave out the
final
as well, as Java 8 has the concept of "effectively final" which applies if you do not modify the variable after initialization.As the JLS specifies:
And generally about happens-before relationships, it says:
Anything that happened before the call to
start()
is guaranteed to be visible inside yourRunnable
task.