मैं एक इंटर-थ्रेड संचार तंत्र की तलाश में हूं जो एक ही समय में अंतर्निहित थ्रेड संसाधन का इंतजार और रिलीज कर सके। नीचे मेरे उदाहरण में, जब executorService को केवल 1 थ्रेड के साथ प्रारंभ किया जाता है, तो दूसरा कार्य अटक जाएगा क्योंकि थ्रेड t1 द्वारा आयोजित किया जाता है, भले ही वह await हो। नीचे दिया गया कोड तभी काम करेगा जब आप executorService को 2 थ्रेड्स के साथ इनिशियलाइज़ करने के लिए बदलते हैं।

public static void main(String[] args) {
  ExecutorService executorService = Executors.newFixedThreadPool(1);
  CountDownLatch cdl = new CountDownLatch(1);

  executorService.submit(() -> {
    System.out.println("start t1");
    try {
      cdl.await();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println("t1 done");
  });

  executorService.submit(() -> {
    System.out.println("start t2");
    cdl.countDown();
    System.out.println("t2 done");
  });

  System.out.println("Master thread ends");
}

आउटपुट जब executorService को 1 थ्रेड के साथ इनिशियलाइज़ किया जाता है।

start t1
Master thread ends

आउटपुट जब executorService को 2 थ्रेड्स के साथ इनिशियलाइज़ किया जाता है।

start t1
Master thread ends
start t2
t2 done
t1 done

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

पुन: प्रयास के लिए एक अलग थ्रेड पूल बनाना इस समस्या को हल कर सकता है, लेकिन मुझे आश्चर्य है कि क्या जावा एक इंटर-थ्रेड संचार तंत्र प्रदान करता है जो एक ही समय में अंतर्निहित थ्रेड को प्रतीक्षा और रिलीज़ करने की अनुमति देता है, ताकि केवल 1 थ्रेड पूल की आवश्यकता हो।

1
Chen 2 अगस्त 2020, 00:07

1 उत्तर

सबसे बढ़िया उत्तर

अंतर्निहित थ्रेड संसाधन को जारी करने का एकमात्र तरीका कार्य की मुख्य विधि (आमतौर पर रननेबल :: रन) से पूरी तरह से वापस आना है। एक ही समय में प्रतीक्षा करने के लिए, ईवेंट निर्माता को एसिंक्रोनस तरीके से सब्सक्राइब किया जाना चाहिए। प्रत्येक निर्माता के पास एसिंक्रोनस इंटरफ़ेस नहीं होता है। CompletbleFuture है (विधि जब पूर्ण), लेकिन CountDownLatch नहीं है। हालाँकि, आप काउंटडाउनचैच को एसिंक्रोनस फ़िक्शनलिटी के साथ बढ़ा सकते हैं, इसके पूरा होने की सदस्यता ले सकते हैं, रन () से वापस आ सकते हैं और प्रतीक्षा कर सकते हैं। मैंने अपनी DF4J लाइब्रेरी में ऐसा किया: AsyncCountDownLatch.java

0
Alexei Kaigorodov 2 अगस्त 2020, 15:19