Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
644 views
in Technique[技术] by (71.8m points)

concurrency - Why lambda inside map is not running?

I am trying to learn concurrency and lambdas in java 8. But my code is not entering lambda block inside map.

List<Book> bookList = new ArrayList<Book>();
    isbnList
    .stream()
    .map(isbn -> (CompletableFuture.supplyAsync( () -> {
        try {
            List<String> pageContents = getUrlContents(webLink + isbn);
            return new Book(
                parseBookTitle(pageContents),
                isbn,
                parseRank(pageContents)
            );
        } catch (IOException ex) {
            return null;
        }
    })).thenApply(a -> bookList.add(a))
    );

While debugging, code is exiting at .map line and I m getting empty bookList. Sequential code for same is giving me correct result.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A stream pipeline is lazy. Without a terminal operation, your stream pipeline is not even executed. Stream.map is an intermediate operation so it won't trigger pipeline execution.

Now you could add a forEach step with the lambda expression cf -> cf.join() for joining on your created CompletableFuture instances for your pipeline to be executed and wait for each of your async futures to complete. But doing this way will defeat the whole purpose of using asynchronous futures, because you're submitting them sequentially and waiting on the completion of each one before submitting the next one.

Better yet, you could convert your stream to a parallel stream, use map with your async lambda body directly by removing the CompletableFuture.supplyAsync part and collecting with collect for a similar effect without the extra clutter.

List<Book> bookList = isbnList.parallelStream()
    .map(isbn -> {
        try {
            List<String> pageContents = getUrlContents(webLink + isbn);
            return new Book(
                parseBookTitle(pageContents),
                isbn,
                parseRank(pageContents)
            );
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }).collect(Collectors.toList());

Further reading: Stream operations and pipelines in the stream API javadoc.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...