When you google for multi-threaded java server, most of the time you'll get a solution based on a following pattern:
public class MultiThreadServer implements Runnable {
private Socket socket;
MultiThreadServer(Socket socket) {
this.socket = socket;
}
public static void main(String args[]) throws Exception {
ServerSocket serverSocket = new ServerSocket(4444);
while (true) {
new Thread(new MultiThreadServer(serverSocket.accept())).start();
}
}
public void run() {
// ...
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// ...
}
}
How does that relate to safe publication idioms presented in Java Concurrency in Practice?
To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:
- Initializing an object reference from a static initializer.
- Storing a reference to it into a volatile field.
- Storing a reference to it into a final field.
- Storing a reference to it into a field that is properly guarded by a (synchronized) lock.
Is it really safe to use socket
within run()
method without any extra synchronization, is it safely published? Please do write more than just yes or no.