जावा में कार्य कतारें: ExecutorService और ThreadPoolExecutor
जावा में मल्टीथ्रेडेड एप्लिकेशन में, कार्यों और उनके निष्पादन का प्रबंधन एक प्रमुख कार्य है। प्रत्येक कार्य के लिए नया थ्रेड बनाने (जो महंगा और अकुशल है) के बजाय, डेवलपर्स थ्रेड पूल के साथ कार्य कतारों (Task Queues) का उपयोग करते हैं। यह एक साथ काम करने वाले थ्रेड्स की संख्या को नियंत्रित करने, उन्हें पुन: उपयोग करने और पीक लोड को सुचारू रूप से संभालने की अनुमति देता है।
जावा में कार्य कतारों के साथ काम करने का आधार Java 5 में प्रस्तुत फ्रेमवर्क java.util.concurrent है। मुख्य घटक हैं: ExecutorService, ThreadPoolExecutor, और BlockingQueue के विभिन्न कार्यान्वयन।
1. ExecutorService — उच्च-स्तरीय इंटरफ़ेस
ExecutorService एक इंटरफ़ेस है जो कार्यों को एसिंक्रोनस रूप से निष्पादित करने के तरीके प्रदान करता है। यह थ्रेड प्रबंधन के विवरणों को छुपाता है। इसका इंस्टेंस प्राप्त करने का सबसे लोकप्रिय तरीका Executors क्लास के फैक्ट्री मेथड का उपयोग करना है:
ExecutorService executor = Executors.newFixedThreadPool(4); // 4 थ्रेड का पूलexecutor.submit(() -> { System.out.println("कार्य थ्रेड में निष्पादित हो रहा है: " + Thread.currentThread().getName());});executor.shutdown(); // सभी कार्यों के पूरा होने के बाद समाप्तिहालांकि, फैक्ट्री मेथड में सीमित कॉन्फ़िगरेशन क्षमताएं होती हैं। बारीक ट्यूनिंग के लिए सीधे ThreadPoolExecutor का उपयोग किया जाता है।
2. ThreadPoolExecutor — अनुकूलन योग्य थ्रेड पूल
ThreadPoolExecutor फ्रेमवर्क का मूल है। यह कार्य कतार, संतृप्ति नीति, थ्रेड का जीवनकाल और अन्य पैरामीटर स्वीकार करता है। पूर्ण कंस्ट्रक्टर:
public ThreadPoolExecutor( int corePoolSize, // न्यूनतम थ्रेड्स की संख्या int maximumPoolSize, // अधिकतम थ्रेड्स की संख्या long keepAliveTime, // थ्रेड को हटाने से पहले निष्क्रिय समय TimeUnit unit, // समय की इकाई BlockingQueue<Runnable> workQueue, // कार्य कतार RejectedExecutionHandler handler // अतिप्रवाह पर नीति);कस्टम कतार के साथ पूल बनाने का उदाहरण:
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(100);ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 4, 30, TimeUnit.SECONDS, queue, new ThreadPoolExecutor.AbortPolicy() // डिफ़ॉल्ट — अपवाद फेंकना);executor.execute(() -> { // भारी कार्य});executor.shutdown();3. BlockingQueue — कार्य कतार का आधार
कतार का प्रकार यह निर्धारित करता है कि कार्य कैसे संग्रहीत और थ्रेड्स को स्थानांतरित किए जाएंगे। सबसे लोकप्रिय कार्यान्वयन:
LinkedBlockingQueue— लिंक्ड लिस्ट पर आधारित असीमित कतार। यदि capacity सेट नहीं की गई है, तो मेमोरी ओवरफ्लो हो सकता है।ArrayBlockingQueue— ऐरे पर आधारित सीमित कतार। यह प्रतीक्षा कर रहे कार्यों की संख्या को नियंत्रित करने की अनुमति देता है।SynchronousQueue— शून्य क्षमता वाली कतार। प्रत्येक कार्य सीधे थ्रेड को स्थानांतरित किया जाता है, कतार में कोई प्रतीक्षा नहीं होती।PriorityBlockingQueue— प्राथमिकता वाली कतार। कार्य प्राथमिकता के अनुसार क्रमबद्ध होते हैं (Comparableलागू करते हैं)।
सीमित कतार और अस्वीकृति नीति के साथ उदाहरण:
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 5, 10, TimeUnit.SECONDS, queue, new ThreadPoolExecutor.CallerRunsPolicy() // कार्य कॉल करने वाले थ्रेड में निष्पादित होता है);for (int i = 0; i < 20; i++) { executor.submit(() -> { Thread.sleep(100); return Math.random(); });}executor.shutdown();4. संतृप्ति नीतियां (RejectedExecutionHandler)
जब कतार भर जाती है