创建一个线程并在类的构造函数中调用它的start()方法是否正确?
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() {
}
}
答案 0 :(得分:11)
this
引用在构造期间转义。
答案 1 :(得分:2)
当然,你的代码没有这样做但是如果你的代码看起来像这样:
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
}
}
即使没有发生异常,服务器引用也可能为null。这是因为即使你的类的构造函数还没有完成,Thread也会使用创建的runnable并调用run方法。
答案 2 :(得分:1)
Server s = new Server();
Thread t = new Thread(s, "Server").start();
更容易测试。它允许您创建一个Server实例并对其方法进行单元测试,而不会产生一个线程。
答案 3 :(得分:1)
将Thread.start()与构造函数分开的几个更好的理由:
如果您想要中断线程,则需要引用它。在单独的代码行中创建线程使得这更常规/惯用。 e.g。
线程rememberMe =新线程(服务器).start();
在原始代码中,服务器可以有一个字段来记住myThread,但它没有。
答案 4 :(得分:1)
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(){
}
}