2012-01-13 8 views
6

क्या यह धागा बनाने के लिए सही है और यहां कक्षा के कन्स्ट्रक्टर के अंदर अपनी स्टार्ट() विधि को कॉल किया गया है?अंदर नए धागे को बुला रहा है कन्स्ट्रक्टर

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

उत्तर

11

आईएमएचओ, ऐसा मत करो। आप निर्माण के दौरान भागने के लिए this संदर्भ की अनुमति दे रहे हैं।

+0

क्या आप इसे समझा सकते हैं? – Mazzy

+0

@Mazzy, आप किसी अन्य ऑब्जेक्ट को आंशिक रूप से निर्मित ऑब्जेक्ट देखने की अनुमति दे रहे हैं, जिसका गंभीर नकारात्मक दुष्प्रभाव हो सकता है। – mre

+1

आप नकारात्मक साइड इफेक्ट्स के बिना वांछित प्रभाव प्राप्त करने के लिए एक स्थिर फैक्ट्री विधि का उपयोग कर सकते हैं। – emory

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

अधिक परीक्षण योग्य है। यह आपको सर्वर का एक उदाहरण बनाने की अनुमति देता है और इकाई थ्रेड के बिना अपने तरीकों का परीक्षण करता है।

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

सर्वर संदर्भ अशक्त भले ही कोई अपवाद तब होता है हो सकता है। ऐसा इसलिए है क्योंकि थ्रेड बनाए गए रननेबल का उपयोग करेगा और रन क्लास का आह्वान करेगा भले ही आपकी कक्षा का कन्स्ट्रक्टर समाप्त नहीं हुआ हो।

1

एक जोड़े को और अधिक अच्छे कारणों के निर्माता से Thread.start() विभाजित करने के लिए:

  1. क्या तुमने कभी इस तरह के एक java.util के रूप में सूत्र, चलाने के लिए कुछ अन्य ढांचे/प्रणाली उपयोग करना चाहते हैं। समवर्ती। निर्माता, आप ऐसा कर सकते हैं।
  2. यदि आप कभी भी धागे को बाधित करना चाहते हैं, तो आपको इसके संदर्भ की आवश्यकता है। थ्रेड को कोड की एक अलग पंक्ति में बनाना कुछ हद तक अधिक नियमित/मूर्खतापूर्ण बनाता है। जैसे

    थ्रेड याद रखें मैं = नया थ्रेड (सर्वर) .start();

आपके मूल कोड में, सर्वर को मेरे थ्रेड को याद रखने के लिए एक फ़ील्ड हो सकता है, लेकिन ऐसा नहीं हुआ।

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

मूल्य रिटर्न सर्वर जोड़ने का क्या अर्थ है? – Mazzy

+0

यदि आप बनाए गए सर्वर का संदर्भ चाहते हैं तो यह आवश्यक है। यदि आप बस एक सर्वर बनाना और शुरू करना चाहते हैं, तो इसकी आवश्यकता नहीं है। – emory

+0

@emory, +1 यह 'newInstance' दृष्टिकोण के समान है। – mre

संबंधित मुद्दे