2015-11-30 2 views
8

में सही ढंग से @Async का उपयोग कैसे करें मुझे वसंत के @Async एनोटेशन और सही तरीके से इसका उपयोग करने के बारे में एक प्रश्न है। मान लीजिए कि मैं इन तरीकों करते हैं:वसंत

@Async 
public void test(String param1) { 
    test2(param1, null); 
} 

@Async 
public void test2(String param1, String param2) { 
    test3(param1, param2, null); 
} 

@Async 
public void test3(String param1, String param2, String param3) { 
    // do some heavy work 
} 

मैं तीनों विधियों के लिए यह अतुल्यकालिक रूप से कहा जा पर @Async की आवश्यकता है या यह पर्याप्त है केवल test3 लिए चालू रखना है कि वास्तव में काम करेंगे है?

+0

वास्तव में मेरे प्रश्न का उत्तर नहीं है, केवल यह कहता है कि 'Async' ब्लॉक असीमित रूप से चलाया जाएगा। –

उत्तर

3

आपको केवल एक विधि में इसकी आवश्यकता है। सिर्फ इसलिए, पहले @Async -method के साथ एक नया धागा शुरू होने के बाद, invoking विधि के लिए असीमित है।

लेकिन क्या यह आपके लिए मतलब है, अत्यधिक क्या आपके उदाहरण उदाहरण देकर स्पष्ट करना चाहिए पर निर्भर करता है:

1) तो आपके मामले में, test1(String param1) के लिए एक @Async पर्याप्त है जब आप कभी भी test1 के माध्यम से test2 और test3 आह्वान।

@Async 
public void test1(String param1) { 
    test2(param1, null); 
} 

private void test2(String param1, String param2) { 
    test3(param1, param2, null); 
} 

private void test3(String param1, String param2, String param3) { 
    // do something 
} 

ध्यान दें कि तरीकों 2 और 3 निजी हैं


2) लेकिन अगर आपके उदाहरण के लिए एक विधि डिफ़ॉल्ट पैरामीटर के लिए पैटर्न (Method chaining अधिक भार को दर्शाता हुआ के लिए है), तो यह है अधिक जटिल फिर आपको असली सामग्री करने वाली विधि पर @Async एनोटेशन होना होगा। क्योंकि आप केवल एक एसिंक-मार्ग में असली निष्पादन निष्पादित करना चाहते हैं, लेकिन प्रत्येक चेनिंग चरण के लिए एक async आमंत्रण नहीं है।

public void test(String param1) { 
    test(param1, null); 
} 


public void test(String param1, String param2) { 
    //this invocation runs async only when real AspectJ is used 
    test(param1, param2, null); 
} 

@Async 
public void test(String param1, String param2, String param3) { 
    // do something 
} 

ध्यान दें कि सभी तरीकों नाम हैं सिर्फ test (विधि श्रृंखलन पैटर्न)

इस के साथ समस्या यह है, कि वसंत (बिना वास्तविक AspectJ load- या संकलन समय बुनाई) नहीं चलेंगे एक विधि async अगर इसे this के माध्यम से बुलाया जाता है! (देखें https://stackoverflow.com/a/22561903/280244)

+0

हां, वे वास्तव में ओवरलोडेड विधियां हैं, मुझे नहीं पता कि मैंने उन्हें टेस्ट 1, टेस्ट 2 और टेस्ट 3 क्यों कहा है ... तो मूल रूप से, विधि जो कुछ एसिंक काम करती है (इस मामले में 'test3''), सार्वजनिक होना चाहिए वास्तव में असीमित होने के लिए (क्योंकि मैं AspectJ का उपयोग नहीं कर रहा हूँ)? दूसरों को एनोटेशन से परेशान नहीं होना चाहिए? –

0

केवल तीसरी विधि test3 पर @Async का उपयोग करने के लिए पर्याप्त है, क्योंकि उस वस्तु कारण स्थानीय स्तर पर बुला प्रॉक्सी नहीं है और केवल प्रॉक्सी वस्तुओं (कंटेनर से उठाया, जैसे @Autowired उपयोग करते हुए) नहीं है async

कॉल भी लग रही है here

2

मुझे लगता है कि @ राल्फ आपकी चिंताओं को ढंकता है।

लेकिन जैसे प्रश्न का नाम है "कैसे स्प्रिंग में सही ढंग से @Async उपयोग करने के लिए", मैं इस उल्लेख करना होगा:

तुम हमेशा वसंत में (या कम से कम बदलने के लिए विचार करें) डिफ़ॉल्ट कार्य निष्पादक बदलना चाहिए संदर्भ या कस्टम कार्य निष्पादक का उपयोग करें।

Because:

डिफ़ॉल्ट रूप से, एक SimpleAsyncTaskExecutor async विधि आमंत्रण पर कार्रवाई करने के लिए इस्तेमाल किया जाएगा।

and:

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