2012-03-30 19 views
10

समस्या का वर्णन: -प्रतीक्षा पूरा: जावा

चरण 1: मुख्य थ्रेड पर उपयोगकर्ता से इनपुट FILE_NAME लो।

चरण 2: उस फ़ाइल पर 10 संचालन करें (यानी अक्षर गिनें, गिनती लाइन आदि ..), और उन सभी 10 संचालन सेप्टेट थ्रेड में होना चाहिए। इसका मतलब है कि 10 बच्चे धागे होना चाहिए।

चरण 3: मुख्य धागा तब तक प्रतीक्षा करता है जब तक कि उन सभी बच्चे धागे पूरा नहीं हो जाते।

चरण 4: प्रिंट परिणाम।

मैं क्या किया: -

मैं 3 धागे के साथ एक नमूना कोड किया था। मैं आपकी तरफ से फाइल ऑपरेशन कोड नहीं चाहता हूं।

public class ThreadTest { 
    // This is object to synchronize on. 
    private static final Object waitObject = ThreadTest.class; 
    // Your boolean. 
    private static boolean boolValue = false; 

    public final Result result = new Result(); 

    public static void main(String[] args) { 
     final ThreadTest mytest = new ThreadTest(); 

     System.out.println("main started"); 

     new Thread(new Runnable() { 

      public void run() { 
       System.out.println("Inside thread"); 

       //Int initialiser 
       new Thread(new Runnable() { 

        public void run() { 
         System.out.println("Setting integer value"); 
         mytest.result.setIntValue(346635); 
         System.out.println("Integer value seted"); 
         try { 
          Thread.sleep(1000); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       }).start(); 

       //String initialiser 
       new Thread(new Runnable() { 

        public void run() { 
         System.out.println("Setting string value"); 
         mytest.result.setStringValue("Hello hi"); 
         System.out.println("String value seted"); 
         try { 
          Thread.sleep(1000); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       }).start(); 

       //Boolean initialiser 
       new Thread(new Runnable() { 

        public void run() { 
         System.out.println("Setting boolean value"); 
         mytest.result.setBoolValue(true); 
         System.out.println("Boolean value seted"); 
         try { 
          Thread.sleep(1000); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       }).start(); 

       System.out.println("Thread is finished"); 

       //Notify to main thread 
       synchronized (ThreadTest.waitObject) { 
        ThreadTest.boolValue = true; 
        ThreadTest.waitObject.notifyAll(); 
       }    
      } 
     }).start(); 

     try { 
      synchronized (ThreadTest.waitObject) { 
       while (!ThreadTest.boolValue) { 
        ThreadTest.waitObject.wait(); 
       } 
      } 
     } catch (InterruptedException ie) { 
      ie.printStackTrace(); 
     } 

     System.out.println("main finished"); 
     System.out.println("Result is : " + mytest.result.toString()); 
    } 
} 

समस्या: -

मेरे ऊपर कोड सही जवाब देने नहीं है। मैं उसे कैसे कर सकता हूँ?

वैकल्पिक समाधान:

CountDownLatch वर्ग ही करता है। लेकिन मैं उस वर्ग का उपयोग नहीं करना चाहता।

मैंने this similar solution देखा और मैं केवल थ्रेड के तरीकों का उपयोग करना चाहता हूं।

+8

थ्रेड के .join() विधि के बारे में पढ़ें। – shift66

+0

यदि यह होमवर्क है तो आपको इसे अगली बार कचरा करना चाहिए। – Voo

उत्तर

29

आप कर सकते हैं:

Thread t = new Thread() { 
    public void run() { 
     System.out.println("text"); 
     // other complex code 
    } 
}; 
t.start(); 
t.join(); 

इस तरह आप धागा खत्म होने तक इंतजार करेंगे और सिर्फ तब जारी है। आप कर सकते हैं join से अधिक थ्रेड:

for (Thread thread : threads) { 
    thread.join(); 
} 
+0

शामिल है() केवल समाधान है? या मेरे दिए गए उदाहरण में कुछ कोड संशोधित करके मैं ऐसा कर सकता हूं? – Andy

+0

यह सबसे अच्छा, सबसे सही और सलाह देने योग्य समाधान है। शायद आप इसे अन्य तरीकों से कर सकते हैं, लेकिन मैं आपको चेतावनी देता हूं - धागे से निपटना कठिन है और जितना आप कर सकते हैं लाइब्रेरी कार्यों में रहते हैं। –

+1

मैंने कोशिश की लेकिन एक धागा अन्य धागे को निष्पादित करने के लिए इंतजार कर रहा है। सभी धागे एक ही समय में निष्पादित नहीं कर रहे हैं। मैं सभी धागे शुरू करना चाहता हूं और उन सभी तक इंतजार कर रहा हूं जब तक कि वे सभी समाप्त नहीं हो जाते। –

10

मैं Executors ढांचे में पहले देख सिफारिश करेंगे, और फिर CompletionService पर गौर।

ExecutorService executor = Executors.newFixedThreadPool(maxThreadsToUse); 
CompletionService completion = new ExecutorCompletionService(executor); 
for (each sub task) { 
    completion.submit(new SomeTaskYouCreate()) 
} 
// wait for all tasks to complete. 
for (int i = 0; i < numberOfSubTasks; ++i) { 
    completion.take(); // will block until the next sub task has completed. 
} 
executor.shutdown(); 
+0

पूर्णता सेवा निर्दिष्ट करने के लिए धन्यवाद ... पिछले 1 दिन से इसकी तलाश है :) – xyz

1

इस दृष्टिकोण के लिए कई तरीके हैं:

तो फिर तुम कुछ इस तरह लिख सकते हैं। CountDownLatch पर विचार करें:

import java.util.concurrent.CountDownLatch; 

public class WorkerTest { 
    final int NUM_JOBS = 3; 
    final CountDownLatch countDownLatch = new CountDownLatch(NUM_JOBS); 
    final Object mutex = new Object(); 
    int workData = 0; 

    public static void main(String[] args) throws Exception { 
     WorkerTest workerTest = new WorkerTest(); 
     workerTest.go(); 
     workerTest.awaitAndReportData(); 
    } 

    private void go() { 
     for (int i = 0; i < NUM_JOBS; i++) { 
      final int fI = i; 
      Thread t = new Thread() { 
       public void run() { 
        synchronized(mutex) { 
         workData++; 
        } 
        try { 
         Thread.sleep(fI * 1000); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
        countDownLatch.countDown(); 
       } 
      }; 
      t.start(); 
     } 
    } 

    private void awaitAndReportData() throws InterruptedException { 
     countDownLatch.await(); 
     synchronized(mutex) { 
      System.out.println("All workers done. workData=" + workData); 
     } 
    } 
} 
1

आप java.util.concurrent से CountDownLatch चुन सकते हैं। Javadocs से:

एक तुल्यकालन सहायता जो एक या अधिक सूत्र जब तक संचालन के सेट अन्य धागे में किया जा रहा है पूरा करता प्रतीक्षा करने के लिए अनुमति देता है।

नमूना कोड:

import java.util.concurrent.CountDownLatch; 

public class Test { 
    private final ChildThread[] children; 
    private final CountDownLatch latch; 

    public Test() { 
     this.children = new ChildThread[4]; 
     this.latch = new CountDownLatch(children.length); 
     children[0] = new ChildThread(latch, "Task 1"); 
     children[1] = new ChildThread(latch, "Task 2"); 
     children[2] = new ChildThread(latch, "Task 3"); 
     children[3] = new ChildThread(latch, "Task 4"); 
    } 

    public void run() { 
     startChildThreads(); 
     waitForChildThreadsToComplete(); 
    } 

    private void startChildThreads() { 
     Thread[] threads = new Thread[children.length]; 

     for (int i = 0; i < threads.length; i++) { 
      ChildThread child = children[i]; 
      threads[i] = new Thread(child); 
      threads[i].start(); 
     } 
    } 

    private void waitForChildThreadsToComplete() { 
     try { 
      latch.await(); 
      System.out.println("All child threads have completed."); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    private class ChildThread implements Runnable { 
     private final String name; 
     private final CountDownLatch latch; 

     protected ChildThread(CountDownLatch latch, String name) { 
      this.latch = latch; 
      this.name = name; 
     } 

     @Override 
     public void run() { 
      try { 
       // Implementation 
       System.out.println(name + " has completed."); 
      } finally { 
       latch.countDown(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     Test test = new Test(); 
     test.run(); 
    } 
} 

आउटपुट:

कार्य 1 पूरा कर लिया है। कार्य 4 पूरा हो गया है। कार्य 3 पूरा हो गया है। कार्य 2 पूरा हो गया है। सभी बच्चे धागे पूरा हो गए हैं।

2

जावा 8 कहीं ज्यादा बेहतर दृष्टिकोण में parallelStream उपयोग करने के लिए है()

नोट: यह अब तक वास्तव में इन पृष्ठभूमि कार्य क्या कर रहे हैं देखने के लिए आसान है।

public static void main(String[] args) { 
    Stream.<Runnable>of(
     () -> mytest.result.setIntValue(346635), 
     () -> mytest.result.setStringValue("Hello hi"), 
     () -> mytest.result.setBoolValue(true)) 
     .parallel() 
     .forEach(Runnable::run); 

    System.out.println("main finished"); 
    System.out.println("Result is : " + mytest.result.toString()); 
} 

मैंने डीबग जानकारी और नींद ली, क्योंकि परिणाम न बदलते हैं।

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