Java Concurrency in Practice Listing 6.2

266 views Asked by At

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?

1

There are 1 answers

0
Erwin Bolwidt On

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:

A call to start() on a thread happens-before any actions in the started thread.

And generally about happens-before relationships, it says:

Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.

Anything that happened before the call to start() is guaranteed to be visible inside your Runnable task.