2012-07-22 21 views
5

मान लीजिए मेरे पास एक मास्टर है जो स्लेव थ्रेड ऑब्जेक्ट्स की एक सूची रखता है। प्रत्येक बार कदम पर, मैं चाहता हूं कि मास्टर समानांतर में स्लेव थ्रेड चलाए, हालांकि, समय के अंत में, मैं चाहता हूं कि स्लेव थ्रेड्स आगे बढ़ने से पहले वर्तमान समय चरण को पूरा करने के लिए एक-दूसरे की प्रतीक्षा करें। साथ ही, मैं प्रत्येक बार चरण पर स्लेव थ्रेड को पुनर्स्थापित नहीं करना चाहता हूं। मेरे पास 2 संभावित समाधान हैं, और मुझे नहीं पता कि उनमें से कोई भी काम कैसे करें:जावा - समय-चरण आधार पर एकाधिक धागे सिंक्रनाइज़ करना

1) स्लेव थ्रेड में रन() विधि थोड़ी देर (सत्य) लूप में है। SlaveThread SlaveThread में एक भी पाश के निष्पादन के बाद, मैं होगा मास्टर (जो मैं कैसे करना है पता नहीं है) को सूचित, और मास्टर से पहले

try{ 
    for (int i = 0; i < numSlaveThreads; i++) { 
     while (!slaveThreads[i].getCompletedThisIter()) { 
     wait() 
     } 
     } 
    System.out.println("Joined"); 

कुछ}

करता है अगली बार कदम आगे बढ़ना। यह मैं कैसे करूंगा? मैं एक स्लेव थ्रेड कैसे मास्टर को सूचित कर सकता हूं?

2) स्लेव में रन() जबकि (सत्य) लूप में नहीं है, तो मुझे प्रत्येक पुनरावृत्ति पर प्रारंभ() पर कॉल करना होगा। लेकिन इस बिंदु पर दास की धागा स्थिति समाप्त हो जाएगी। मैं इसे फिर से शुरू किए बिना फिर से शुरू() कैसे कॉल कर सकता हूं?

+0

लगता है कि आपका चक्रीय बाधा हैं: http://docs.oracle.com/javase/7/docs/api /java/util/concurrent/CyclicBarrier.html (संस्करण का उपयोग 1.) – millimoose

उत्तर

5

यह वास्तव में बाधाओं के लिए है, आप इसे CyclicBarrier या CountDownLatch के साथ महसूस कर सकते हैं। ये पर सिंक्रनाइज़र्स हैं जो वांछित स्थिति तक पहुंचने तक की प्रगति में देरी करते हैं, आपके मामले में धागे ने उनकी गणना पूरी की है।

यहाँ यह विवरणों पर निर्भर करता है कि कैसे आप महसूस करना चाहते हैं:

सिटकनी की घटनाओं के लिए इंतजार कर के लिए कर रहे हैं; बाधाएं अन्य धागे की प्रतीक्षा के लिए हैं।

CyclicBarrier कि निम्नलिखित फैशन में किया जाएगा के लिए: barrier.await()

public class Slaves implements Runnable { 

    // ... 

    @Override 
    public void run() { 

     while(condition) { 

     // computation 
     // ... 

     try { 
      // do not proceed, until all [count] threads 
      // have reached this position 
      barrier.await(); 
     } catch (InterruptedException ex) { 
      return; 
     } catch (BrokenBarrierException ex) { 
      return; 
     } 
     } 
    } 
} 

:

// whereby count is the number of your slave threads 
this.barrier = new CyclicBarrier(count); 

फिर अपने दासों की Runnable परिभाषा आप गणना के अंत में दर्ज हो जाएगा आपके दास धागे आगे नहीं बढ़ेंगे, जब तक आपके सभी धागे गणना नहीं कर लेते। इस तरह आपको किसी अन्य मास्टर थ्रेड के बीच सिग्नलिंग का एहसास करने की आवश्यकता नहीं है।

अगर, हालांकि, आप कुछ कोड आप के बाद सभी धागे उस स्थिति (मास्टर संकेतन) पर पहुँच गए हैं निष्पादित करने के लिए आप CyclicBarrier निर्माता, जिसके बाद सभी धागे बाधा पर आ चुके हैं निष्पादित किया जाएगा के लिए एक अतिरिक्त Runnable पारित कर सकते हैं करना चाहते हैं ।

this.barrier = new CyclicBarrier(count, 
    new Runnable() { 
     @Override 
     public void run() { 
     // signal your master thread, update values, etc. 
     } 
    } 
); 
+0

मैं मास्टर को यह बताने के लिए अन्य धागे की प्रतीक्षा करना चाहता हूं कि वे अपने वर्तमान पुनरावृत्ति के साथ किए गए हैं (ताकि वे सभी एक ही समय में आगे बढ़ सकें एक) – Trup

+0

मैं 1 पुनरावृत्ति के अंत में चक्रीय बाधा को गिनती कैसे शुरू करूं? आपने कहा कि प्रतीक्षा करने के लिए प्रत्येक धागा() 0 तक गिर जाता है जब तक यह 0 तक नहीं पहुंच जाता है, लेकिन उस बिंदु पर, मैं काउंटर को numThreads पर पुनरारंभ करना चाहता हूं, ताकि अगला चक्र निष्पादित हो जाए। – Trup

+0

@Trup आपको इसके बारे में चिंता करने की ज़रूरत नहीं है, यह स्वचालित रूप से होता है, यही कारण है कि इसे * चक्रीय * बाधा कहा जाता है, इसे जितनी बार चाहें उतनी बार पुन: उपयोग किया जा सकता है। –

3

आप अपने धागे प्रबंधन के लिए एक ExecutorService के संयोजन का उपयोग कर सकता है (अर्थात आप प्रत्येक चक्र पर नए बनाने के लिए बिना अपने धागे रीसायकल) और एक CyclicBarrier जो सभी दास सिंक्रनाइज़ किए जाएंगे।

एक साधारण उदाहरण के नीचे देखें जहां मास्टर ने लूप में गुलामों को लॉन्च किया है, यह सुनिश्चित कर लें कि वे फिर से शुरू होने से पहले किए गए हैं।दास, थोड़ा आलसी जा रहा है, बस कुछ (वास्तव में यादृच्छिक नहीं) समय के लिए सो:

public class Test { 

    private static final ExecutorService executor = Executors.newFixedThreadPool(5); 
    private static final CyclicBarrier barrier = new CyclicBarrier(5); //4 slaves + 1 master 

    public static void main(String[] args) throws InterruptedException { 
     Runnable master = new Runnable() { 
      @Override 
      public void run() { 
       try { 
        while (true) { 
         System.out.println("Starting slaves"); 
         for (int i = 100; i < 500; i += 100) { 
          executor.submit(getRunnable(i)); 
         } 
         barrier.await(); 
         System.out.println("All slaves done"); 
        } 
       } catch (InterruptedException | BrokenBarrierException ex) { 
        System.out.println("Bye Bye"); 
       } 
      } 
     }; 

     executor.submit(master); 
     Thread.sleep(2000); 
     executor.shutdownNow(); 

    } 

    public static Runnable getRunnable(final int sleepTime) { 
     return new Runnable() { 
      @Override 
      public void run() { 
       try { 
        System.out.println("Entering thread " + Thread.currentThread() + " for " + sleepTime + " ms."); 
        Thread.sleep(sleepTime); 
        System.out.println("Exiting thread " + Thread.currentThread()); 
        barrier.await(); 
       } catch (BrokenBarrierException | InterruptedException ex) { 
       } 
      } 
     }; 

    } 
} 
+0

दासों के लिए कोड कौन सा है? साथ ही, क्या मैं इसे चक्रीय बाधा के साथ कर सकता हूं और निष्पादन सेवा नहीं कर सकता? क्या आप मुझे दिखा सकते हैं कि यह कैसा दिखता है? असल में, मैं स्पष्ट रूप से देखना चाहता हूं कि दास चक्रीय बाधा को बताता है कि यह कैसे किया जाता है, और कैसे मास्टर सभी गुलामों को खत्म करने की प्रतीक्षा करने के लिए चक्रीय बाधा का उपयोग करता है। धन्यवाद! – Trup

+0

गुलामों के रननेबल 'getRunnable (i) 'द्वारा उत्पन्न होते हैं। आप निष्पादक सेवा के बिना एक साइकिल चालक का उपयोग कर सकते हैं। आपको केवल सही संख्या के साथ बाधा स्थापित करने की आवश्यकता है। हर बार 'barrier.await()' कहा जाता है, कॉलिंग थ्रेड इंतजार करता है और वह संख्या घट जाती है। जब संख्या 0 तक पहुंच जाती है तो सभी प्रतीक्षा धागे फिर से काम करना शुरू कर देते हैं। – assylias

+0

मेरा सुझाव है कि आप प्रोग्राम को चलाएं जो मैंने पोस्ट किया है यह देखने के लिए कि यह कैसे काम करता है और आपकी आवश्यकताओं के लिए इसे अनुकूलित करता है। – assylias

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