竞争条件,较小的请求优先于较大的Java 8异步

时间:2018-12-20 18:22:00

标签: java asynchronous java-8 callback jersey-client

我提供带有基本URL的函数getArtifactDataList(),并返回2个InputStream的列表。 InputStreams的大小应该不同,因为它们是我下载的非常不同的工件。但是它们是相同的。

代码:

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.16</version>
    </dependency>
import org.apache.commons.io.IOUtils;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


private static final String DOWNLOAD_1 = "http://some.random/host/artifact.zip";
private static final String DOWNLOAD_2 = "http://random.other/host/artifact2.zip"


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

    List<InputStream> artifactData = getArtifactDataList();

    for(InputStream is : artifactData) {
        System.out.println("Size: "+ IOUtils.toByteArray(is).length);
    }
}

public static final List<InputStream> getArtifactDataList() throws Exception {

    List<InputStream> listData = new ArrayList<>();

    URL downloadUrl = UriBuilder.fromUri(DOWNLOAD_1).buildFromMap(new HashMap<>()).toURL();

    final InputStream data = requestData(downloadUrl); // should be 20MB in size


    URL downloadFontsUrl = UriBuilder.fromUri(DOWNLOAD_2).buildFromMap(new HashMap<>()).toURL();
    final InputStream fontsData = requestData(downloadFontsUrl); // should be 1MB in size

    listData.add(fontsData);
    listData.add(data);

    return listData;
}

public static final InputStream requestData(URL url) {
    Client c = ClientBuilder.newClient();
    WebTarget resource = c.target(url.toString());

    Invocation.Builder request = resource.request();
    request.accept(MediaType.APPLICATION_XML);

    final InputStream data =
            request.get().readEntity(InputStream.class);

    return data;
}

输出

  

大小:1MB

     

大小:1MB

似乎2个请求中的较小者(fontsData)以某种方式覆盖了2个请求中的较大者。我几乎不知道发生了什么。看起来像一个竞争条件,但我不想同步requestData函数。还有其他一些很直接使用的解决方案吗?也许Java期货还是Promises?在我的情况下如何使用?谁能告诉我这里真正发生了什么?如何解决这个问题?

编辑: 此代码旨在说明我的问题。我将流添加到列表中。还添加了网址生成器(我认为这不相关)

工作示例

0 个答案:

没有答案