Calling a new thread inside is a constructor

Is it correct to create a stream and call its start () method inside the class constructor, as is done here?

public class Server implements Runnable { private ServerSocket server; public Server(int port) { try { //Opens a new server server = new ServerSocket(port); } catch (IOException ioe) { ioe.printStackTrace(); } new Thread(this, "Server").start(); } @Override public void run() { } } 
+6
source share
5 answers

IMHO, do not do this. You allow the this link to escape at build time.

+11
source

Of course, your code does not do this, but what if your code looks like this:

 public Server(int port) { new Thread(this, "Server").start(); try { //Opens a new server server = new ServerSocket(port); } catch (IOException ioe){ ioe.printStackTrace(); } } @Override public void run(){ if(server == null)throw new NullPointerException();// this may happen } } 

The server link may be null, even if an exception does not occur. This is because Thread will use the created runnable and call the run method, even if the constructor of your class has not finished yet.

+2
source
 Server s = new Server(); Thread t = new Thread(s, "Server").start(); 

is more verifiable. This allows you to instantiate the server and unit test its methods without creating a thread.

+1
source

A few more good reasons to split Thread.start () from the constructor:

  • If you ever want to use some other frameworks / systems to start threads, like java.util.concurrent.Executor, you can do this.
  • If you want to interrupt a stream, you need a link to it. Creating a stream in a separate line of code makes this somewhat more common / idiomatic. eg.

    Thread memMe = new Thread (server) .start ();

In the source code, the server may have a field for remembering myThread, but this is not so.

+1
source
 public class Server implements Runnable { private ServerSocket server; /** * Because the constructor is private, the only way to instantiate a Server is through * the static factory method. * If there are any instantiation problems, the static factory method will fail in * first line, before it is put into a thread. * It will be put into a thread before being released. **/ public static Server startServer ( int port ) { Server server = new Server ( port ) ; new Thread ( server , "Server" ) . start ( ) ; return server ; } private Server(int port) { try { //Opens a new server server = new ServerSocket(port); } catch (IOException ioe){ ioe.printStackTrace(); } // don't release me into the wild yet! // new Thread(this, "Server").start(); } @Override public void run(){ } } 
+1
source

Source: https://habr.com/ru/post/905936/


All Articles