bhh1988
bhh1988

Reputation: 1290

Java Concurrency in Practice Listing 6.2

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?

Upvotes: 3

Views: 269

Answers (1)

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31269

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.

Upvotes: 2

Related Questions