Java # Cync / प्रतीक्षारत का समकक्ष?


151

मैं एक सामान्य C # डेवलपर हूं लेकिन कभी-कभी मैं जावा में एप्लिकेशन विकसित करता हूं। अगर C # async / प्रतीक्षा के बराबर कोई जावा है तो मैं सोच रहा हूँ? सरल शब्दों में जावा क्या समकक्ष है:

async Task<int> AccessTheWebAsync()
{ 
    HttpClient client = new HttpClient();
    var urlContents = await client.GetStringAsync("http://msdn.microsoft.com");
    return urlContents.Length;
}

7
यह अच्छा क्यों होगा: हमारी जेनेरेशनों के बयान के रूप में कॉलबैक मिगुएल डे इकाजा द्वारा जाना जाता है।
andrewdotn

जावा का वर्तमान समाधान वास्तविक उपसर्गों से निपटने के लिए नहीं है async, बल्कि इसके बजाय उपयोग Futureया Observableमूल्यों के साथ है।
एसडी

1
कोई समकक्ष नहीं है। और यह दर्द देता है। एक और अधिक लापता विशेषता के लिए आपको जटिल वर्कअराउंड और पुस्तकालयों की आवश्यकता होती है, कभी भी इन दो, सरल शब्दों के समान प्रभाव तक पहुंचने के बिना।
स्पाईरो

यह ध्यान देने योग्य है कि एक लंबे समय के लिए, जावा डिजाइनरों ने मौजूदा सुविधाओं के आसपास केवल पुस्तकालयों और सिंथेटिक-चीनी में परिवर्तन के साथ जावा बाइटकोड को पिछड़े रखने की कोशिश की है। इस तथ्य को देखें कि जेनरिक रन-टाइम प्रकार की जानकारी संग्रहीत नहीं करते हैं और लैम्बर्स को एक इंटरफ़ेस को लागू करने वाली वस्तु के रूप में लागू किया जाता है । async / प्रतीक्षा को संभव होने के लिए bytecode में बहुत बड़े बदलावों की आवश्यकता होगी और इसलिए मैं इसे किसी भी समय जावा में देखने की उम्मीद नहीं करूंगा।
फिलिप कूपन

जवाबों:


140

नहीं, जावा में async / वेट का कोई समतुल्य नहीं है - या v5 से पहले C # में भी।

यह पर्दे के पीछे एक राज्य मशीन बनाने के लिए एक काफी जटिल भाषा सुविधा है।

जावा में अतुल्यकालिक / संगामिति के लिए अपेक्षाकृत कम भाषा समर्थन है, लेकिन java.util.concurrentपैकेज में इसके चारों ओर बहुत उपयोगी कक्षाएं हैं । (टास्क पैरेलल लाइब्रेरी के बिल्कुल बराबर नहीं है, लेकिन इसके लिए निकटतम सन्निकटन है।)


15
@ user960567: नहीं, मेरा कहना है कि यह एक भाषा की विशेषता है - इसे केवल पुस्तकालयों में नहीं रखा जा सकता है। मेरा मानना ​​है कि जावा 8 के लिए कोई भी समतुल्य निर्धारित नहीं है।
जॉन स्कीट

10
@ user960567: आपको C # के संस्करण और आपके द्वारा उपयोग किए जा रहे .NET के संस्करण के बीच अंतर करने की आवश्यकता है। async / wait एक भाषा विशेषता है - इसे C # 5. में पेश किया गया था। हाँ, आप Microsoft का उपयोग कर सकते हैं। Bcl.Async का उपयोग करने के लिए async / प्रतीक्षा लक्ष्य .NET 4 का उपयोग करें, लेकिन आपको अभी भी C # 5 संकलक का उपयोग करना है।
जॉन स्कीट

5
@rozar: नहीं, वास्तव में नहीं। अतुल्यकालिक के लिए पहले से ही कई विकल्प हैं - लेकिन RxJava उस तरह से भाषा को नहीं बदलता है जैसा कि C # ने किया था। मेरे पास Rx के खिलाफ कुछ भी नहीं है, लेकिन यह सी # 5 में async के समान नहीं है।
जॉन स्कीट

11
@DtechNet: वैसे तो बहुत सारी JVM मशीनरी है जो एसिंक्रोनस है, हाँ ... यह वहाँ से अलग है, हालांकि वास्तविक भाषा सुविधाएँ अतुल्यकालिक का समर्थन कर रही हैं । (Async / प्रतीक्षा से पहले .NET में बहुत अधिक अतुल्यकालिक था, लेकिन ... async / प्रतीक्षा से इसका लाभ लेना बहुत आसान हो जाता है।)
जॉन स्कीट

1
@ अरकोन: मैं तर्क दूंगा कि जब तक स्पष्ट भाषा समर्थन नहीं है, तब तक उत्तर सही है। यह सिर्फ पुस्तकालयों की बात नहीं है जो शेड्यूलिंग को सरल बनाते हैं - जिस तरह से सी # कंपाइलर एक राज्य मशीन का निर्माण करता है वह यहाँ महत्वपूर्ण है।
जॉन स्कीट

41

awaitअतुल्यकालिक ऑपरेशन पूरा होने ( client.GetStringAsync(...)) पर अतिरिक्त कोड को निष्पादित करने के लिए एक निरंतरता का उपयोग करता है ।

इसलिए, सबसे निकट सन्निकटन के रूप में, मैं एसिंक्रोनस रूप से Http अनुरोध को संसाधित करने के लिए एक CompletableFuture<T>(जावा 8 के बराबर .net Task<TResult>) आधारित समाधान का उपयोग करूंगा ।

२५-०५-२०१६ को २०१६-२०१६ के अब्रिल १३ तारीख को जारी AsyncHttpClient v.2 पर अद्यतन :

तो जावा 8 के ओपी उदाहरण के बराबर AccessTheWebAsync()निम्नलिखित है:

CompletableFuture<Integer> AccessTheWebAsync()
{
    AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient();
    return asyncHttpClient
       .prepareGet("http://msdn.microsoft.com")
       .execute()
       .toCompletableFuture()
       .thenApply(Response::getResponseBody)
       .thenApply(String::length);
}

यह उपयोग इस उत्तर से लिया गया था कि मुझे Async Http क्लाइंट के अनुरोध से कंप्लीटटेबल फाउल कैसे मिलेगा? और जो 2016 के Abril 13th पर जारी AsyncHttpClient के संस्करण 2 में प्रदान किए गए नए एपीआई के अनुसार है , जो पहले से ही आंतरिक समर्थन है CompletableFuture<T>

AsyncHttpClient के संस्करण 1 का उपयोग करके मूल उत्तर:

उस अंत तक हमारे पास दो संभावित दृष्टिकोण हैं:

  • पहला गैर-अवरुद्ध IO का उपयोग करता है और मैं इसे कॉल करता हूं AccessTheWebAsyncNio। फिर भी, क्योंकि AsyncCompletionHandlerएक सार वर्ग है (एक कार्यात्मक इंटरफ़ेस के बजाय) हम एक लंबो को तर्क के रूप में पारित नहीं कर सकते। तो यह अनाम वर्गों के वाक्यविन्यास के कारण अपरिहार्य क्रिया में बदल जाता है। हालांकि, यह समाधान दिए गए C # उदाहरण के निष्पादन प्रवाह के सबसे करीब है

  • दूसरा एक थोड़ा कम क्रिया है लेकिन यह एक नया कार्य प्रस्तुत करेगा जो अंततः f.get()प्रतिक्रिया पूरा होने तक एक थ्रेड को ब्लॉक करेगा ।

पहला तरीका , अधिक क्रिया लेकिन गैर-अवरोधक:

static CompletableFuture<Integer> AccessTheWebAsyncNio(){
    final AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
    final CompletableFuture<Integer> promise = new CompletableFuture<>();
    asyncHttpClient
        .prepareGet("https://msdn.microsoft.com")
        .execute(new AsyncCompletionHandler<Response>(){
            @Override
            public Response onCompleted(Response resp) throws Exception {
                promise.complete(resp.getResponseBody().length());
                return resp;
            }
        });
    return promise;
}

दूसरा तरीका कम क्रिया है लेकिन एक धागा को अवरुद्ध करना:

static CompletableFuture<Integer> AccessTheWebAsync(){
    try(AsyncHttpClient asyncHttpClient = new AsyncHttpClient()){
        Future<Response> f = asyncHttpClient
            .prepareGet("https://msdn.microsoft.com")
            .execute();
        return CompletableFuture.supplyAsync(
            () -> return f.join().getResponseBody().length());
    }
}

1
वास्तव में, यह खुश प्रवाह के बराबर है। यह अपवादों, अंत में और दूसरों को संभालने को कवर नहीं करता है। उन्हें शामिल करने से कोड बहुत अधिक जटिल हो जाएगा और त्रुटियों के लिए अधिक प्रवण होगा।
haimb

1
यह एक निरंतरता नहीं है। यह उदाहरण async / प्रतीक्षा के वास्तविक उद्देश्य को याद करता है, जो कि अन्य चीजों को निष्पादित करने के लिए वर्तमान थ्रेड को जारी करना है, और फिर प्रतिक्रिया आने के बाद वर्तमान थ्रेड पर इस पद्धति का निष्पादन जारी रखना है। (यह या तो UI थ्रेड के लिए आवश्यक है, उत्तरदायी हो, या मेमोरी उपयोग को कम करने के लिए।) यह जो उदाहरण देता है वह एक सादे ब्लॉकिंग थ्रेड सिंक्रोनाइज़ेशन है, साथ ही कुछ कॉलबैक भी हैं।
Aleksandr Dubinsky

1
@AleksandrDubinsky मैं आपसे सहमत हूं जब आप इंगित करते हैं कि कॉलर थ्रेड पर कॉलबैक नहीं चल सकता है। तुम सही हो। मैं एक धागे को अवरुद्ध करने के बारे में असहमत हूं। 25-05-2016 को अपडेट किया गया मेरा अद्यतन उत्तर गैर-अवरुद्ध है।
मिगुएल गैंबोआ

1
.... और यह नमूना वास्तव में यही कारण है कि अतुल्यकालिक सामान करते समय C # लिखना और पढ़ना इतना सरल है। यह सिर्फ जावा में एक दर्द है।
जासूसी

29

की जाँच करें ईए-async जो करने के लिए अनुकरण async / इंतजार बहुत अच्छी तरह से फिर से लिखने बाईटकोड जावा करता है। उनकी रीडमी के अनुसार: "यह .NET CLR पर Async-Await से बहुत अधिक प्रेरित है"


8
क्या कोई इसका उत्पादन में उपयोग करता है?
मिस्टर.वांग नेक्स्ट डोर

1
ऐसा लगता है कि ईए करता है, मुझे नहीं लगता कि वे किसी ऐसी चीज पर पैसा खर्च करेंगे जो उत्पादन के लिए उपयुक्त नहीं है।
ब्रूनो जेसीएम

1
किसी चीज़ पर पैसा खर्च करना बहुत सामान्य है और फिर तय करना है कि यह उत्पादन के लिए उपयुक्त नहीं है; यह सीखने का एकमात्र तरीका है। उत्पादन में जावा एजेंट सेटिंग्स के बिना इसका उपयोग करना संभव है; उस पट्टी को थोड़ा कम करना चाहिए ( github.com/electronicarts/ea-async )।
18'18

16

async और इंतजार वाक्यात्मक शर्करा हैं। एसिंक्स और वेट का सार राज्य मशीन है। कंपाइलर आपके async / प्रतीक्षा कोड को स्टेट मशीन में बदल देगा।

एक ही समय में, वास्तविक परियोजनाओं में वास्तव में व्यावहारिक होने के लिए async / प्रतीक्षा के लिए, हमें पहले से ही बहुत सारे Async I / O लाइब्रेरी फ़ंक्शंस होने चाहिए। C # के लिए, सबसे मूल सिंक्रनाइज़ I / O फ़ंक्शन का एक वैकल्पिक Async संस्करण है। हमें इन Async फ़ंक्शंस की आवश्यकता है क्योंकि ज्यादातर मामलों में, आपका खुद का async / प्रतीक्षा कोड कुछ लाइब्रेरी Async विधि के लिए उबाल देगा।

C # में Async संस्करण लायब्रेरी फ़ंक्शंस जावा में AsynchronousChannel अवधारणा की तरह है। उदाहरण के लिए, हमारे पास AsynchronousFileChannel.read है जो या तो फ्यूचर वापस कर सकता है या रीड ऑपरेशन के बाद कॉलबैक निष्पादित कर सकता है। लेकिन यह बिल्कुल वैसा नहीं है। सभी C # Async फ़ंक्शंस टास्क लौटाते हैं (भविष्य के समान लेकिन भविष्य से अधिक शक्तिशाली)।

तो मान लें कि Java async / प्रतीक्षा का समर्थन करता है, और हम कुछ कोड इस तरह लिखते हैं:

public static async Future<Byte> readFirstByteAsync(String filePath) {
    Path path = Paths.get(filePath);
    AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);

    ByteBuffer buffer = ByteBuffer.allocate(100_000);
    await channel.read(buffer, 0, buffer, this);
    return buffer.get(0);
}

तब मुझे लगता है कि कंपाइलर मूल async / प्रतीक्षा कोड को कुछ इस तरह से बदल देगा:

public static Future<Byte> readFirstByteAsync(String filePath) {

    CompletableFuture<Byte> result = new CompletableFuture<Byte>();

    AsyncHandler ah = new AsyncHandler(result, filePath);

    ah.completed(null, null);

    return result;
}

और यहाँ AsyncHandler के लिए कार्यान्वयन है:

class AsyncHandler implements CompletionHandler<Integer, ByteBuffer>
{
    CompletableFuture<Byte> future;
    int state;
    String filePath;

    public AsyncHandler(CompletableFuture<Byte> future, String filePath)
    {
        this.future = future;
        this.state = 0;
        this.filePath = filePath;
    }

    @Override
    public void completed(Integer arg0, ByteBuffer arg1) {
        try {
            if (state == 0) {
                state = 1;
                Path path = Paths.get(filePath);
                AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);

                ByteBuffer buffer = ByteBuffer.allocate(100_000);
                channel.read(buffer, 0, buffer, this);
                return;
            } else {
                Byte ret = arg1.get(0);
                future.complete(ret);
            }

        } catch (Exception e) {
            future.completeExceptionally(e);
        }
    }

    @Override
    public void failed(Throwable arg0, ByteBuffer arg1) {
        future.completeExceptionally(arg0);
    }
}

15
सिंथेटिक चीनी? क्या आपको पता है कि async कोड के आस-पास अपवादों को कैसे लपेटें, और async कोड के आसपास लूप्स?
आकाश काव

39
कक्षाएं, भी, वाक्यात्मक चीनी हैं। संकलक सभी पेड़ों और फ़ंक्शन पॉइंटर्स की सूची बनाता है जिन्हें आप सामान्य रूप से हाथ से पूरी तरह से स्वचालित रूप से लिखते हैं। ये कार्य / विधियाँ वाक्यगत शर्करा भी हैं। वे सामान्य रूप से एक वास्तविक प्रोग्रामर होने के नाते, सभी गोटो को ऑटो-जनरेट करते हैं, हाथ से लिखते हैं। असेम्बलर सिंटैक्टिक शुगर है। वास्तविक प्रोग्रामर मैन्युअल रूप से मशीन कोड लिखते हैं और मैन्युअल रूप से इसे सभी लक्ष्य आर्किटेक्चर में पोर्ट करते हैं।
तुर्क

32
अबू इट्ट सोचने के लिए, कंप्यूटर खुद l4m3 n00bz के लिए सिंटैक्टिक शुगर हैं। असली प्रोग्रामर उन्हें छोटे एकीकृत सर्किट को एक लकड़ी के बोर्ड में मिलाप करते हैं और उन्हें सोने के तार से जोड़ते हैं क्योंकि सर्किट बोर्ड सिंटैक्टिक चीनी होते हैं, जैसे बड़े पैमाने पर उत्पादन, जूते, या भोजन।
तुर्क

14

भाषा स्तर पर जावा में C # async / प्रतीक्षा का कोई समतुल्य नहीं है। फाइबर्स उर्फ कोऑपरेटिव थ्रेड्स उर्फ लाइटवेट थ्रेड्स के रूप में जाना जाने वाला एक अवधारणा एक दिलचस्प विकल्प हो सकता है। आप फाइबर के लिए समर्थन प्रदान करने वाले जावा पुस्तकालय पा सकते हैं।

फाइबर्स को लागू करने वाले जावा पुस्तकालय

तंतुओं के अच्छे परिचय के लिए आप यह लेख (क्वासर से) पढ़ सकते हैं । यह कवर करता है कि धागे क्या हैं, जेवीएम पर फाइबर कैसे लागू किया जा सकता है और इसमें कुछ क्वासर विशिष्ट कोड हैं।


10
Async / Cit में प्रतीक्षारत फाइबर नहीं है। यह सिर्फ कंपाइलर मैजिक है जो Taskकॉलबैक दर्ज करके प्रॉमिस ( क्लास) पर निरंतरता का उपयोग करता है ।
अल्टिमावेपॉन

1
@UltimaWeapon तो क्या आप फाइबर होना मानते हैं?
अलेक्सांद्र डबिन्सकी

@AleksandrDubinsky का एक उदाहरण गोरोइन है।
अल्टिमावेपॉन

1
@UltimaWeapon मैं एक स्पष्टीकरण के लिए देख रहा था।
अलेक्सांद्र डबिन्सकी

@AleksandrDubinsky मैं इसे समझाने में आलसी हूँ। यदि आप वास्तव में जानना चाहते हैं, तो आप इस लेख के बारे में खोज कर सकते हैं गोरोइन के हुड के नीचे।
अल्टिमावेपन

8

जैसा कि यह उल्लेख किया गया था, कोई प्रत्यक्ष समकक्ष नहीं है, लेकिन जावा बायोटेकोड संशोधनों (दोनों async / प्रतीक्षा-जैसा निर्देश और अंतर्निहित निरंतरता कार्यान्वयन) के साथ बहुत निकट सन्निकटन बनाया जा सकता है।

मैं अभी एक ऐसी परियोजना पर काम कर रहा हूं जो JavaFlow निरंतरता लाइब्रेरी के शीर्ष पर async / प्रतीक्षा का कार्यान्वयन करता है , कृपया https://github.com/vsilaev/java-async-await देखें

कोई मावेन मोजो अभी तक नहीं बना है, लेकिन आप आपूर्ति किए गए जावा एजेंट के साथ उदाहरण चला सकते हैं। यहाँ बताया गया है कि async / प्रतीक्षित कोड कैसा दिखता है:

public class AsyncAwaitNioFileChannelDemo {

public static void main(final String[] argv) throws Exception {

    ...
    final AsyncAwaitNioFileChannelDemo demo = new AsyncAwaitNioFileChannelDemo();
    final CompletionStage<String> result = demo.processFile("./.project");
    System.out.println("Returned to caller " + LocalTime.now());
    ...
}


public @async CompletionStage<String> processFile(final String fileName) throws IOException {
    final Path path = Paths.get(new File(fileName).toURI());
    try (
            final AsyncFileChannel file = new AsyncFileChannel(
                path, Collections.singleton(StandardOpenOption.READ), null
            );              
            final FileLock lock = await(file.lockAll(true))
        ) {

        System.out.println("In process, shared lock: " + lock);
        final ByteBuffer buffer = ByteBuffer.allocateDirect((int)file.size());

        await( file.read(buffer, 0L) );
        System.out.println("In process, bytes read: " + buffer);
        buffer.rewind();

        final String result = processBytes(buffer);

        return asyncResult(result);

    } catch (final IOException ex) {
        ex.printStackTrace(System.out);
        throw ex;
    }
}

@async एनोटेशन है जो एक विधि को अतुल्यकालिक रूप से निष्पादन योग्य के रूप में चिह्नित करता है, वेट () एक ऐसा फ़ंक्शन है जो निरंतरताओं का उपयोग करके कंपेटिबलफ़्यूच्युलेट पर प्रतीक्षा करता है और "asyncResult (someValue) को वापस करने के लिए एक कॉल है जो कि कंप्लीट फ़ाइबिटेबल सीवन / निरंतरता को अंतिम रूप देता है।

सी # के साथ के रूप में, नियंत्रण प्रवाह संरक्षित है और अपवाद हैंडलिंग नियमित रूप से किया जा सकता है (क्रमिक रूप से निष्पादित कोड में प्रयास करें / पकड़ें)


6

जावा में स्वयं की कोई समान विशेषताएं नहीं हैं, लेकिन तृतीय-पक्ष पुस्तकालय मौजूद हैं जो समान कार्यक्षमता प्रदान करते हैं, उदाहरण के लिए किलिम


3
मुझे नहीं लगता है कि इस पुस्तकालय के पास कुछ भी नहीं है जो async / इंतजार करता है।
नाटन

5

सबसे पहले, समझें कि async / प्रतीक्षा क्या है। यह एक एकल-थ्रेडेड GUI एप्लिकेशन या एक कुशल सर्वर के लिए एक ही धागे पर कई "फाइबर" या "सह-दिनचर्या" या "हल्के धागे" चलाने का एक तरीका है।

यदि आप साधारण थ्रेड्स का उपयोग करने के साथ ठीक हैं, तो जावा समकक्ष है ExecutorService.submitऔर Future.get। यह कार्य पूरा होने तक अवरुद्ध हो जाएगा, और परिणाम लौटाएगा। इस बीच, अन्य सूत्र काम कर सकते हैं।

यदि आप फाइबर जैसी किसी चीज का लाभ चाहते हैं, तो आपको कंटेनर में समर्थन चाहिए (मेरा मतलब जीयूआई इवेंट लूप या सर्वर HTTP रिक्वेस्ट हैंडलर में), या अपना खुद का लिखकर।

उदाहरण के लिए, सर्वलेट 3.0 अतुल्यकालिक प्रसंस्करण प्रदान करता है। JavaFX ऑफर करता है javafx.concurrent.Task। हालांकि इनमें भाषा की विशेषताओं का लालित्य नहीं है, हालांकि। वे साधारण कॉलबैक के माध्यम से काम करते हैं।


2
यहाँ इस उत्तर के पहले पैराग्राफ को पुनः आरंभ करने वाला एक लेख उद्धरण है। प्रारंभ उद्धरण ग्राहक अनुप्रयोगों के लिए, जैसे कि विंडोज स्टोर, विंडोज डेस्कटॉप और विंडोज फोन ऐप, async का प्राथमिक लाभ जवाबदेही है। इस प्रकार के ऐप यूआई को उत्तरदायी बनाए रखने के लिए मुख्य रूप से एसिंक् यू का उपयोग करते हैं। सर्वर अनुप्रयोगों के लिए, एसिंक्स का प्राथमिक लाभ स्केलेबिलिटी है। msdn.microsoft.com/en-us/magazine/dn802603.aspx
granadaCoder

3

जावा में कुछ भी ऐसा नहीं है जो आपको async / wait कीवर्ड की तरह यह करने की अनुमति देता है, लेकिन अगर आप वास्तव में काउंटडाउन लाइक का उपयोग करना चाहते हैं तो आप क्या कर सकते हैं । फिर आप इसे पास (कम से कम Java7 में) पास करके async / प्रतीक्षा कर सकते हैं । यह एंड्रॉइड यूनिट टेस्टिंग में एक आम बात है, जहां हमें एक async कॉल करना होता है (आमतौर पर एक हैंडलर द्वारा रन करने योग्य पोस्ट), और फिर रिजल्ट (काउंट डाउन) का इंतजार करना होता है।

हालाँकि आपके परीक्षण के विरोध में आपके आवेदन के अंदर इसका उपयोग नहीं किया गया है । यह बेहद घटिया होगा क्योंकि काउंटडाउनचैच आप पर निर्भर करता है कि आप कितनी बार सही संख्या में और सही स्थानों पर गिनती करते हैं।


3

मैं जावा async / प्रतीक्षा लाइब्रेरी को बनाता और जारी करता हूं। https://github.com/stofu1234/kamaitachi

इस लाइब्रेरी को संकलक विस्तार की आवश्यकता नहीं है, और जावा में स्टैकलेस आईओ प्रसंस्करण का एहसास करें।

    async Task<int> AccessTheWebAsync(){ 
        HttpClient client= new HttpClient();
        var urlContents= await client.GetStringAsync("http://msdn.microsoft.com");
       return urlContents.Length;
    }

   ↓

    //LikeWebApplicationTester.java
    BlockingQueue<Integer> AccessTheWebAsync() {
       HttpClient client = new HttpClient();
       return awaiter.await(
            () -> client.GetStringAsync("http://msdn.microsoft.com"),
            urlContents -> {
                return urlContents.length();
            });
    }
    public void doget(){
        BlockingQueue<Integer> lengthQueue=AccessTheWebAsync();
        awaiter.awaitVoid(()->lengthQueue.take(),
            length->{
                System.out.println("Length:"+length);
            }
            );
    }

1

जावा के पास दुर्भाग्य से async / प्रतीक्षा के बराबर नहीं है। निकटतम आप प्राप्त कर सकते हैं शायद अमरूद और श्रोता की श्रवण से सुने जाने योग्य सामान के साथ, लेकिन कई अतुल्यकालिक कॉल वाले मामलों के लिए लिखना अभी भी बहुत बोझिल होगा, क्योंकि घोंसले का स्तर बहुत जल्दी बढ़ेगा।

यदि आप JVM के शीर्ष पर एक अलग भाषा का उपयोग करने के साथ ठीक हैं, तो सौभाग्य से Scala में async / प्रतीक्षारत है जो एक सीधा C # async / प्रतीक्षारत है जो लगभग समान वाक्यविन्यास और शब्दार्थ के बराबर है: https://github.com/scala async /

ध्यान दें कि हालांकि इस कार्यक्षमता के लिए C # में एक बहुत उन्नत कंपाइलर समर्थन की आवश्यकता थी, स्काला में इसे स्काला में एक बहुत शक्तिशाली मैक्रो सिस्टम के लिए धन्यवाद के रूप में एक पुस्तकालय के रूप में जोड़ा जा सकता है और इसलिए 2.10 जैसे स्केल के पुराने संस्करणों में भी जोड़ा जा सकता है। इसके अतिरिक्त स्काला जावा के साथ वर्ग-संगत है, इसलिए आप स्कैला में async कोड लिख सकते हैं और फिर इसे जावा से कॉल कर सकते हैं।

इसी तरह का एक और प्रोजेक्ट भी है जिसका नाम अक्का डाटाफ्लो http://doc.akka.io/docs/akka/2.3-M1/scala/dataflow.html है, जो अलग-अलग शब्दों का उपयोग करता है, लेकिन वैचारिक रूप से बहुत समान है, हालांकि सीमांकित निरंतरता का उपयोग करके लागू किया जाता है, मैक्रोज़ नहीं। (इसलिए यह 2.9 जैसे पुराने स्केल संस्करणों के साथ काम करता है)।


1

जावा में सी # भाषा सुविधा का सीधा समकक्ष नहीं है जिसे async / wait कहा जाता है, हालाँकि समस्या के लिए एक अलग दृष्टिकोण है जिसे async / wait हल करने का प्रयास करता है। इसे प्रोजेक्ट लूम कहा जाता है , जो उच्च-थ्रूपुट संगति के लिए आभासी धागे प्रदान करेगा। यह OpenJDK के कुछ भविष्य के संस्करण में उपलब्ध होगा।

यह दृष्टिकोण " रंगीन फ़ंक्शन समस्या " को भी हल करता है जो कि async / प्रतीक्षा है।

इसी तरह की सुविधा गोलंग ( गोरआउट्स ) में भी पाई जा सकती है ।


0

यदि आप क्लीन कोड के बाद हैं, जो जावा में async / प्रतीक्षा के समान प्रभाव का अनुकरण करता है और इसे समाप्त होने तक थ्रेड को ब्लॉक करने में कोई आपत्ति नहीं है, जैसे कि यह समाप्त हो गया है, जैसे कि एक परीक्षण में, आप इस कोड जैसी किसी चीज़ का उपयोग कर सकते हैं:

interface Async {
    void run(Runnable handler);
}

static void await(Async async) throws InterruptedException {

    final CountDownLatch countDownLatch = new CountDownLatch(1);
    async.run(new Runnable() {

        @Override
        public void run() {
            countDownLatch.countDown();
        }
    });
    countDownLatch.await(YOUR_TIMEOUT_VALUE_IN_SECONDS, TimeUnit.SECONDS);
}

    await(new Async() {
        @Override
        public void run(final Runnable handler) {
            yourAsyncMethod(new CompletionHandler() {

                @Override
                public void completion() {
                    handler.run();
                }
            });
        }
    });

0

AsynHelper जावा पुस्तकालय में ऐसी अतुल्यकालिक कॉल (और प्रतीक्षा) के लिए उपयोगिता वर्गों / विधियों का एक सेट शामिल है।

यह अतुल्यकालिक रूप से विधि कॉल या कोड ब्लॉक का एक सेट चलाने के लिए वांछित है, तो यह एक उपयोगी सहायक विधि शामिल AsyncTask .submitTasks टुकड़ा नीचे के रूप में।

AsyncTask.submitTasks(
    () -> getMethodParam1(arg1, arg2),
    () -> getMethodParam2(arg2, arg3)
    () -> getMethodParam3(arg3, arg4),
    () -> {
             //Some other code to run asynchronously
          }
    );

यदि यह सभी अतुल्यकालिक कोडों को पूरा होने तक प्रतीक्षा करने के लिए वांछित है, तो AsyncTask.submitTasksAndWait वैरिएंट का उपयोग किया जा सकता है।

इसके अलावा अगर यह अतुल्यकालिक विधि कॉल या कोड ब्लॉक में से प्रत्येक से एक रिटर्न वैल्यू प्राप्त करने के लिए वांछित है, तो AsyncSupplier .submitSuppliers का उपयोग किया जा सकता है ताकि परिणाम फिर से प्राप्त किया जा सके परिणाम आपूर्तिकर्ता सरणी विधि द्वारा लौटाया जा सकता है। नीचे नमूना स्निपेट है:

Supplier<Object>[] resultSuppliers = 
   AsyncSupplier.submitSuppliers(
     () -> getMethodParam1(arg1, arg2),
     () -> getMethodParam2(arg3, arg4),
     () -> getMethodParam3(arg5, arg6)
   );

Object a = resultSuppliers[0].get();
Object b = resultSuppliers[1].get();
Object c = resultSuppliers[2].get();

myBigMethod(a,b,c);

यदि प्रत्येक विधि का रिटर्न प्रकार भिन्न होता है, तो नीचे दिए गए स्निपेट का उपयोग करें।

Supplier<String> aResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam1(arg1, arg2));
Supplier<Integer> bResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam2(arg3, arg4));
Supplier<Object> cResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam3(arg5, arg6));

myBigMethod(aResultSupplier.get(), bResultSupplier.get(), cResultSupplier.get());

अतुल्यकालिक विधि कॉल / कोड ब्लॉक का परिणाम एक ही धागे में कोड के एक अलग बिंदु पर या नीचे के स्निपेट में एक अलग धागे के रूप में भी प्राप्त किया जा सकता है।

AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam1(arg1, arg2), "a");
AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam2(arg3, arg4), "b");
AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam3(arg5, arg6), "c");


//Following can be in the same thread or a different thread
Optional<String> aResult = AsyncSupplier.waitAndGetFromSupplier(String.class, "a");
Optional<Integer> bResult = AsyncSupplier.waitAndGetFromSupplier(Integer.class, "b");
Optional<Object> cResult = AsyncSupplier.waitAndGetFromSupplier(Object.class, "c");

 myBigMethod(aResult.get(),bResult.get(),cResult.get());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.