2012-01-13 29 views
6

Có đúng là tạo một luồng và gọi phương thức start() bên trong hàm tạo của lớp như đã hoàn thành ở đây không?gọi chủ đề mới bên trong là hàm tạo

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() { 
    } 
} 

Trả lời

11

IMHO, đừng làm điều này. Bạn đang cho phép tham chiếu this để thoát trong khi xây dựng.

+0

bạn có thể giải thích không? – Mazzy

+0

@Mazzy, Bạn đang cho phép một đối tượng khác xem một đối tượng được xây dựng một phần, có thể có các tác dụng phụ tiêu cực nghiêm trọng. – mre

+1

Bạn có thể sử dụng một phương pháp nhà máy tĩnh để đạt được hiệu quả mong muốn mà không có tác dụng phụ tiêu cực. – emory

1
Server s = new Server(); 
Thread t = new Thread(s, "Server").start(); 

dễ kiểm tra hơn. Nó cho phép bạn tạo một thể hiện của Server và đơn vị kiểm tra các phương thức của nó mà không cần sinh ra một luồng.

2

Cấp, isnt mã của bạn làm việc đó nhưng những gì nếu mã của bạn trông như thế này:

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 
} 
} 

Tham chiếu máy chủ có thể được null mặc dù không có ngoại lệ xảy ra. Điều này là do Thread sẽ sử dụng runnable được tạo ra và gọi phương thức run ngay cả khi constructor của lớp bạn chưa hoàn thành.

1

Một vài lý do tốt hơn để phân chia các Thread.start() từ các nhà xây dựng:

  1. Nếu bạn muốn sử dụng một số khuôn khổ/hệ thống khác để chạy các chủ đề, chẳng hạn như một java.util. concurrent.Executor, bạn có thể làm như vậy.
  2. Nếu bạn muốn ngắt chuỗi, bạn cần tham chiếu đến chuỗi đó. Tạo chủ đề trong một dòng riêng biệt của mã làm cho điều này phần nào thường xuyên hơn/idiomatic. ví dụ.

    Chủ đề RememberMe = new Thread (server) .start();

Trong mã ban đầu của bạn, Máy chủ có thể có trường cần nhớ myThread nhưng không.

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(){ 
} 
} 
+0

Ý nghĩa của việc thêm máy chủ trả về giá trị là gì? – Mazzy

+0

Nó là cần thiết nếu bạn muốn có một tham chiếu đến máy chủ được tạo ra. Nếu bạn chỉ muốn tạo và khởi động một máy chủ, nó không cần thiết. – emory

+0

@emory, +1 Điều này tương tự như cách tiếp cận 'newInstance'. – mre

Các vấn đề liên quan