2013-05-24 13 views
5

मैं सूत्रण जो 1 20 करने के लिए से शुरू जब मैं मुख्य विधि वह निष्पादित सभी धागे के साथ यह परीक्षण किया संख्या के लिए टेबल उत्पन्न करता है के लिए एक सरल उदाहरण लिखा था के अंतर्गत बनाए (सभी संदेश प्रिंट) को क्रियान्वित नहीं, जबकि सभी धागे नहीं चल रहे हैं (सभी संदेशों को मुद्रित नहीं किया जा रहा है) अधिकांश समय (कभी-कभी यह सभी धागे चलाता है) जब जुनीट परीक्षण के साथ ऐसा करते हैं। मुझे लगता है कि उत्पादन के मामले में कोई अंतर नहीं होना चाहिए।JUnit परीक्षण सभी धागे परीक्षण

यहां मुख्य विधि के साथ वर्ग है:

public class Calculator implements Runnable { 

    private int number; 

    Calculator(final int number){ 
     this.number = number; 
    } 

    @Override 
    public void run() { 
     for(int i = 1; i <= 10; i++){ 
      System.out.printf("%s : %d * %d = %d \n", Thread.currentThread().getName(), number, i, number * i); 
     } 

    } 

    public static void main(String[] args){ 
     Calculator calculator = null; 
     Thread thread = null; 
     for(int i = 1; i < 21; i ++){ 
      calculator = new Calculator(i); 
      thread = new Thread(calculator); 
      System.out.println(thread.getName() + " Created"); 
      thread.start(); 
      System.out.println(thread.getName() + " Started"); 
     } 

    } 

} 

जब मैं मुख्य विधि परिणाम ही सब कुछ प्रिंट आह्वान।

public class CalculatorTest { 

private Calculator calculator; 
private Thread thread; 

@Test 
public void testCalculator() { 
    for(int i = 1; i < 21; i ++){ 
     calculator = new Calculator(i); 
     thread = new Thread(calculator); 
     System.out.println(thread.getName() + " Created"); 
     thread.start(); 
     System.out.println(thread.getName() + " Started"); 
    } 
} 

} 

जब मैं ऊपर परीक्षण का मामला चलाने के लिए, उत्पादन के व्यवहार दृश्य में संगत नहीं है कि कभी-कभी सभी संदेशों को प्रिंट:

Bellow मुख्य विधि को JUnit परीक्षण समकक्ष के लिए कोड है और ज्यादातर बार केवल कुछ ही प्रिंट करता है और बाहर निकलता है। यहाँ उत्पादन ऊपर JUnit परीक्षण मामले के मामले में कब्जा कर लिया है:

Thread-0 Created 
Thread-0 Started 
Thread-1 Created 
Thread-1 Started 
Thread-2 Created 
Thread-2 Started 
Thread-3 Created 
Thread-3 Started 
Thread-4 Created 
Thread-4 Started 
Thread-5 Created 
Thread-5 Started 
Thread-6 Created 
Thread-6 Started 
Thread-7 Created 
Thread-7 Started 
Thread-8 Created 
Thread-8 Started 
Thread-9 Created 
Thread-9 Started 
Thread-10 Created 
Thread-10 Started 
Thread-11 Created 
Thread-11 Started 
Thread-12 Created 
Thread-12 Started 
Thread-13 Created 
Thread-13 Started 
Thread-14 Created 
Thread-14 Started 
Thread-15 Created 
Thread-15 Started 
Thread-16 Created 
Thread-16 Started 
Thread-17 Created 
Thread-17 Started 
Thread-18 Created 
Thread-18 Started 
Thread-19 Created 
Thread-19 Started 
Thread-0 : 1 * 1 = 1 
Thread-0 : 1 * 2 = 2 
Thread-0 : 1 * 3 = 3 
Thread-0 : 1 * 4 = 4 
Thread-0 : 1 * 5 = 5 
Thread-0 : 1 * 6 = 6 
Thread-0 : 1 * 7 = 7 
Thread-0 : 1 * 8 = 8 
Thread-0 : 1 * 9 = 9 
Thread-0 : 1 * 10 = 10 
Thread-2 : 3 * 1 = 3 
Thread-2 : 3 * 2 = 6 
Thread-2 : 3 * 3 = 9 
Thread-2 : 3 * 4 = 12 
Thread-2 : 3 * 5 = 15 
Thread-2 : 3 * 6 = 18 
Thread-2 : 3 * 7 = 21 

आउटपुट/अन्य धागे में शेष संदेशों मुद्रण अन्य थ्रेड को क्रियान्वित करने के बिना यहाँ समाप्त होती है।

किसी ने मुझसे इस के पीछे कारण को समझने के लिए मदद कर सकते हैं। अग्रिम में धन्यवाद। पहले सभी पैदा धागे पूरा कर लें

उत्तर

11

JUnit जल्दी परीक्षा पद्धति बाहर निकलने है। testCalculator() विधि से बाहर निकलने से पहले आपको सभी थ्रेडों को पूरा करने की प्रतीक्षा करनी होगी।

ऐसा करने के लिए एक आसान तरीका है एक CountDownLatch उपयोग करना है।

  1. एक CountDownLatchCountDownLatch latch = new CountDownLatch(20) साथ प्रमाणित करें।

  2. पास प्रत्येक Calculator runnable एक कुंडी के संदर्भ में। run() विधि के अंत में, latch.countDown() पर कॉल करें।

  3. testCalculator() विधि कॉल latch.await() के अंत में। यह latch.countDown() तक 20 बार बुलाया जाएगा (यानी जब सभी धागे पूरा हो जाते हैं)।

+0

उत्तर के लिए धन्यवाद। मैं कोशिश करुंगा। –

+0

ठीक है। मुझे तुम्हारा मुद्दा मिला लेकिन फिर भी मैं समझ नहीं पा रहा हूं कि क्यों मुख्य थ्रेड इसे पूरा करने/समाप्त करने के लिए शुरू किए गए सभी धागे के लिए इंतजार कर रहा है, जबकि साथ ही जुनीट टेस्ट थ्रेड इसे अनुमति नहीं दे रहा है। क्या आप इसे समझा सकते हैं। –

+0

क्या आप पूछ रहे हैं कि गिनती नीचे कैसे काम करता है? या आप पूछ रहे हैं कि जब तक सभी धागे पूरा नहीं हो जाते हैं तब तक आपको ब्लॉक करने की आवश्यकता क्यों होती है? –

4

आपका परीक्षा पद्धति खत्म। जब जुनीत के निष्पादक खत्म हो जाते हैं, तो सभी पैदा हुए धागे मारे जाते हैं।

यदि आप इस तरह के परीक्षण को चलाने के लिए चाहते हैं, तो आपको अपनी टेस्ट विधि के अंत में बनाए गए धागे और join() का संग्रह रखना चाहिए। join() पर प्रत्येक थ्रेड को दूसरे लूप में निष्पादित किया जाता है (लूप के बाद जो सभी थ्रेड शुरू होता है)।

+1

यह समानांतरता का लाभ नहीं उठाएगा हालांकि ... केवल एक धागा एक बार में चल रहा होगा। इसके बजाय 'countDownLatch' या 'execorService # invokeAll (सूची )' विधि का उपयोग करके इसके आसपास के तरीके हैं। –

+1

सभी थ्रेडों में मौजूदा लूप में 'प्रारंभ()' कहा जाता है। जवाब परीक्षण विधि के अंत में दूसरा लूप जोड़ना है जो प्रत्येक स्पॉन्डेड थ्रेड पर 'join() 'को कॉल करता है। 'जुड़ें() 'कॉल तब तक वापस नहीं आती जब तक कि वह धागा समाप्त नहीं हो जाता है।समांतरता का पूर्ण लाभ लेता है और यह सुनिश्चित करता है कि लौटने से पहले सभी तैयार धागे किए जाते हैं। CountDownLatch को यह सुनिश्चित करने के लिए सावधानीपूर्वक कोडिंग की आवश्यकता होती है कि प्रत्येक धागे की गणना हो, भले ही इसमें अपवाद हों। निष्पादक सेवा अभी भी आवश्यक है कि आप कॉल करने योग्य (या रननेबल) किए जाने तक प्रतीक्षा करें। – Rob

+0

आह, ठीक है। मैं 'join() 'का उपयोग करने के बारे में सहमत हूं। आप अपने उत्तर में "विधि के अंत में दूसरा लूप" स्पष्ट करना चाहते हैं। 'काउंटरडाउन लॅच' का उपयोग ओपी के लिए ठीक काम करेगा हालांकि ('कैलकुलेटर' रननेबल में कोई अपवाद नहीं डाला गया है)। और 'निष्पादक सेवा' यहां भी सबसे अच्छा विकल्प हो सकता है क्योंकि 20 धागे बनाने के बजाए आप जिस कंप्यूटर पर निष्पादित कर रहे हैं, इससे कोई फर्क नहीं पड़ता कि आप 'Runtime.getRuntime()। उपलब्ध प्रोसेसर() 'थ्रेड का उपयोग करके थ्रेड पूल बना सकते हैं। फिर 'invokeAll() 'को कॉल करने से सभी कॉलबेल निष्पादित हो जाएंगे और जब तक वे पूरा नहीं हो जाएंगे तब तक ब्लॉक करेंगे। –

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