제이온

[स्प्रिंग] @Async का उपयोग कैसे करें

  • लेखन भाषा: कोरियाई
  • आधार देश: सभी देशcountry-flag
  • आईटी

रचना: 2024-04-25

रचना: 2024-04-25 22:33

जावा असिंक्रोनस प्रोसेसिंग

स्प्रिंग @Async को देखने से पहले, सिंक्रोनस, असिंक्रोनस और मल्टी-थ्रेडिंग की अवधारणाएँ आवश्यक हैं। इन अवधारणाओं को जानने की मान्यता के साथ, आइए कोड के माध्यम से शुद्ध जावा असिंक्रोनस प्रोसेसिंग विधि को देखें। यदि आप जावा थ्रेड से परिचित हैं, तो आप इस अध्याय को छोड़ सकते हैं।



यदि आप सिंक्रोनस तरीके से संदेश प्राप्त करते हैं और केवल आउटपुट करते हैं, तो आप ऊपर दिए गए कोड की तरह कोड लिख सकते हैं। इसे मल्टी-थ्रेडिंग असिंक्रोनस विधि में बदलने पर, आप स्रोत कोड को इस प्रकार लिख सकते हैं।



लेकिन इस पद्धति में थ्रेड का प्रबंधन नहीं किया जा सकता है, जो इसे बहुत खतरनाक बनाता है। उदाहरण के लिए, यदि 10,000 कॉल एक साथ किए जाते हैं, तो थ्रेड को बहुत कम समय में 10,000 बार बनाया जाना चाहिए। थ्रेड बनाने की लागत कम नहीं होती है, इसलिए यह प्रोग्राम के प्रदर्शन को नकारात्मक रूप से प्रभावित कर सकता है, और इससे OOM त्रुटि भी हो सकती है। इसलिए, थ्रेड को प्रबंधित करने के लिए, थ्रेड पूल को लागू किया जाना चाहिए, और जावा ExecutorService क्लास प्रदान करता है।



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


स्प्रिंग @Async

सरल तरीका


एप्लीकेशन क्लास के ऊपर @EnableAsync एनोटेशन लगाकर और सिंक्रोनस लॉजिक की उस विधि के ऊपर @Async एनोटेशन लगाकर जिसे हम असिंक्रोनस रूप से संसाधित करना चाहते हैं, यह हो जाता है। लेकिन ऊपर दी गई विधि में थ्रेड का प्रबंधन नहीं किया जाता है। ऐसा इसलिए है क्योंकि @Async की डिफ़ॉल्ट सेटिंग SimpleAsyncTaskExecutor का उपयोग करने के लिए है, जो थ्रेड पूल नहीं है, बल्कि केवल थ्रेड बनाने का काम करता है।


थ्रेड पूल का उपयोग करने का तरीका

सबसे पहले, Application क्लास से @EnableAsync को हटा दें। Application क्लास में @EnableAutoConfiguration या @SpringBootApplication सेटिंग होने पर, रनटाइम पर SpringAsyncConfig क्लास (जिसे हम नीचे बनाएंगे) में कॉन्फ़िगर किए गए threadPoolTaskExecutor बीन की जानकारी पढ़ी जाती है।



आप कोर और अधिकतम आकार सेट कर सकते हैं। इस समय, यह अनुमान लगाया जा सकता है कि यह शुरू में कोर आकार के साथ काम करेगा, और यदि यह उससे अधिक कार्य नहीं संभाल सकता है, तो यह अधिकतम आकार तक बढ़ जाएगा, लेकिन ऐसा नहीं है।


आंतरिक रूप से, यह Integer.MAX_VALUE आकार का LinkedBlockingQueue बनाता है, और यदि कोर आकार के थ्रेड कार्य नहीं संभाल सकते हैं, तो वे कतार में प्रतीक्षा करते हैं। जब कतार भर जाती है, तो यह अधिकतम आकार तक थ्रेड बनाता है और कार्य संभालता है।


यदि आप Integer.MAX_VALUE पर कतार का आकार निर्धारित करने में असहज हैं, तो आप queueCapacity निर्धारित कर सकते हैं। यदि आप इसे ऊपर की तरह सेट करते हैं, तो यह शुरू में 3 थ्रेड के साथ काम करेगा, और यदि प्रसंस्करण गति धीमी हो जाती है, तो यह 100 आकार की कतार में कार्य रखेगा, और यदि इससे अधिक अनुरोध आते हैं, तो यह अधिकतम 30 थ्रेड बनाएगा और कार्य संभालेगा।


थ्रेड पूल सेटिंग पूरी हो जाने के बाद, आपको @Async एनोटेशन वाली विधि में ऊपर दिए गए बीन का नाम जोड़ना होगा।



यदि आप कई प्रकार के थ्रेड पूल सेट करना चाहते हैं, तो आप threadPoolTaskExecutor() जैसी कई बीन बनाने वाली विधियाँ बना सकते हैं, और जब आप @Async सेट करते हैं, तो आप उस थ्रेड पूल बीन को डाल सकते हैं जिसे आप उपयोग करना चाहते हैं।


रिटर्न प्रकार के अनुसार लौटाया गया स्वरूप

रिटर्न मान नहीं होने पर

यह वह स्थिति है जहां असिंक्रोनस रूप से संसाधित की जाने वाली विधि को परिणाम वापस करने की आवश्यकता नहीं है। इस स्थिति में, @Async एनोटेशन का रिटर्न प्रकार void पर सेट किया जाना चाहिए।


रिटर्न मान होने पर

Future, ListenableFuture, CompletableFuture प्रकार को रिटर्न प्रकार के रूप में उपयोग किया जा सकता है। असिंक्रोनस विधि के रिटर्न स्वरूप को new AsyncResult() से बांधें।


[Future]


future.get() अनुरोध के परिणाम के आने तक प्रतीक्षा करने के लिए ब्लॉकिंग का उपयोग करता है। इसलिए, यह असिंक्रोनस ब्लॉकिंग विधि बन जाती है, जिसके कारण प्रदर्शन खराब होता है। आमतौर पर Future का उपयोग नहीं किया जाता है।


[ListenableFuture]


ListenableFuture कॉलबैक के माध्यम से कार्य को गैर-अवरोधी तरीके से संसाधित करने की अनुमति देता है। addCallback() विधि का पहला पैरामीटर कार्य पूर्णता कॉलबैक विधि है, और दूसरा पैरामीटर कार्य विफलता कॉलबैक विधि है। संदर्भ के लिए, चूँकि थ्रेड पूल का कोर थ्रेड 3 पर सेट है, आप देख सकते हैं कि "Task Start" संदेश पहले 3 बार प्रिंट होता है।



[CompletableFuture]

हालांकि ListenableFuture अकेले गैर-अवरोधी तर्क को लागू कर सकता है, यदि कॉलबैक के अंदर एक कॉलबैक की आवश्यकता होती है, तो यह बहुत जटिल कोड उत्पन्न करता है जिसे कॉलबैक नर्क कहा जाता है।


<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F9f152db8-c015-43cd-bf13-85c594f5f218%2FUntitled.png?table=block&id=268ac0bc-ca7b-4bcb-b11b-ac611a5038b2&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/1455;" width="2000" height="1455"></span>


बेशक, हम इस समय CompletableFuture पर विस्तार से चर्चा नहीं करेंगे, इसलिए यदि आप जटिल कॉलबैक को संभालने वाले कोड में रुचि रखते हैं, तो कृपया नीचे दिए गए स्रोत लिंक को देखें।



ListenableFuture में कॉलबैक परिभाषा की तुलना में इसमें बेहतर पठनीयता है, और यह गैर-अवरोधी कार्यक्षमता को पूरी तरह से निष्पादित करता है। इसलिए, जब आप @Async का उपयोग करते हैं और रिटर्न मान की आवश्यकता होती है, तो CompletableFuture का उपयोग करने की अनुशंसा की जाती है।


@Async के लाभ

डेवलपर सिंक्रोनस तरीके से विधियों को लिख सकते हैं, और यदि उन्हें असिंक्रोनस तरीके से संसाधित करने की आवश्यकता होती है, तो वे बस विधि के ऊपर @Async एनोटेशन लगा सकते हैं। इसलिए, आप सिंक्रोनस और असिंक्रोनस के लिए अच्छी तरह से बनाए रखने योग्य कोड बना सकते हैं।


@Async के लिए सावधानियां


  • यदि आप private विधि पर @Async लगाते हैं, तो AOP काम नहीं करेगा।
  • यदि एक ही ऑब्जेक्ट के अंदर की विधियों के बीच कॉल किया जाता है, तो AOP काम नहीं करेगा।


स्रोत

टिप्पणियाँ0

Node.js जूनियर भी बना सकते हैं framework level DIयह लेख Node.js सर्वर विकास में निर्भरता इंजेक्शन (DI) को लागू करने के तरीके के बारे में बताता है। यह बताता है कि TypeScript कंपाइलर के Reflect मेटाडेटा फ़ंक्शन का उपयोग करके DI को कैसे लागू किया जाए और संबंधित लाइब्रेरी का परिचय देता है।
Sunrabbit
Sunrabbit
Sunrabbit
Sunrabbit

November 8, 2024

[गैर-तकनीकी, डेवलपर के रूप में जीवित रहना] 14. नव नियुक्त डेवलपर अक्सर पूछे जाने वाले तकनीकी साक्षात्कार सामग्री सारांशनव नियुक्त डेवलपर साक्षात्कार में अक्सर पूछे जाने वाले तकनीकी प्रश्न (मेमोरी क्षेत्र, डेटा संरचना, डेटाबेस आदि) को संक्षेप में प्रस्तुत किया गया है। डेवलपमेंट इंटरव्यू की तैयारी में यह मददगार होगा।
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

April 3, 2024

स्लैक पर संवाद, इतना व्यवहार तो जरूरी है!स्लैक का कुशलतापूर्वक उपयोग करने के लिए 9 व्यवहारिक सुझाव! उल्लेख, त्वरित उत्तर, थ्रेड का उपयोग आदि सहयोग के लिए संवाद व्यवहार सीखें और कार्य कुशलता में वृद्धि करें।
꿈많은청년들
꿈많은청년들
꿈많은청년들
꿈많은청년들

November 12, 2024

29 नवंबर 2024 की लेट ब्रेकिंग न्यूज़: Replit का पेड सब्सक्रिप्शन / अच्छी सॉफ्टवेयर डेवलपमेंट आदतें29 नवंबर 2024 को लिखे गए इस ब्लॉग पोस्ट में Replit के पेड सब्सक्रिप्शन के अनुभव को साझा किया गया है और अच्छी सॉफ्टवेयर डेवलपमेंट आदतों के 10 सुझाव दिए गए हैं। इसमें कुशल कोडिंग और रिफैक्टरिंग रणनीतियाँ, टेस्टिंग के महत्व आदि पर चर्चा की गई है।
Charles Lee
Charles Lee
Charles Lee
Charles Lee

November 29, 2024

ओपनसोर्स योगदान अनुभवयह लेख ओपनसोर्स योगदान अनुभव साझा करता है, डर पर काबू पाने और पहला कदम उठाने का साहस प्रदान करता है। छोटे सुधारों से शुरुआत करके आत्मविश्वास हासिल करने और बढ़ने की प्रक्रिया के बारे में बताता है।
seungwon
seungwon
seungwon
seungwon

May 3, 2025

उत्पादकता में सुधार के लिए स्वचालन प्रोग्राम बनाते हैं।उत्पादकता में सुधार के लिए स्वचालन प्रोग्राम निर्माण सेवा प्रदान करते हैं। आरपीए, एआई आधारित वेब, दस्तावेज़, ईमेल आदि कार्यों के स्वचालन के माध्यम से दक्षता में वृद्धि करें।
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마

March 22, 2024