繁体   English   中英

如何从URL列表中同时获取InputStreams?

[英]How to concurrently get InputStreams from a list of URLs?

当前,我正在尝试返回一个输入流,该输入流由序列化输入流的列表组成,每个序列化输入流都通过API从自己的网址生成。 问题在于,顺序执行后,API需要花费几秒钟的时间来生成数据。 这样,API在连接期间会缩短几秒钟。 api的结构如下:

www.api.com?q=ENCODEDTEXT

我目前有此代码以按顺序添加它们。

public InputStream getMP3Data(List<String> synthText){
    InputStream complete = getMP3Data(synthText.remove(0));
    for(String part: synthText){
        complete = new java.io.SequenceInputStream(complete, getMP3Data(part));//Concatenate with new MP3 Data
    }
    return complete;
}

getMP3Data(String)是我用于通过自动编码URL并获取输入流来访问URL的方法。 getMP3Data(List)的目的是执行相同的操作,但要包含整个数据列表。 我的问题是如何使用多线程来完成此任务。 我想同时为列表中的每个项目调用getMP3Data(String)。 我将如何完成? 我事先不知道清单的大小。 任何帮助将不胜感激。

编辑:这是我最终使用的。 上述代码执行速度提高了900%以上

    /**
 * Gets an InputStream to MP3Data for the returned information from a request
 * @param synthText List of Strings you want to be synthesized into MP3 data
 * @return Returns an input stream of all the MP3 data that is returned from Google
 * @throws IOException Throws exception if it cannot complete the request
 */
public InputStream getMP3Data(List<String> synthText) throws IOException{
    //Uses an executor service pool for concurrency
    ExecutorService pool = Executors.newFixedThreadPool(synthText.size());
    //Stores the Future (Data that will be returned in the future)
    Set<Future<InputStream>> set = new LinkedHashSet<Future<InputStream>>();
    //Iterates through the list
    for(String part: synthText){
        Callable<InputStream> callable = new MP3DataFetcher(part);//Creates Callable
        Future<InputStream> future = pool.submit(callable);//Runs the Callable
        set.add(future);//Adds the response that will be returned to a set.
    }
    List<InputStream> inputStreams = new ArrayList<InputStream>(set.size());
    for(Future<InputStream> future: set){
        inputStreams.add(future.get());//Gets the response that will be returned, returned.
    }
    return new SequenceInputStream(Collections.enumeration(inputStreams));//Sequences the stream
}


     /**
 * This class is a callable.
 * A callable is like a runnable except that it can return data and throw exceptions.
 * Useful when using futures. 
 * @author Skylion
 *
 */
private class MP3DataFetcher implements Callable<InputStream>{
    private String synthText;

    public MP3DataFetcher(String synthText){
        this.synthText = synthText;
    }

    public InputStream call() throws Exception{
        return getMP3Data(synthText);
    }
}
public InputStream getMP3Data(List<String> synthText){
  List<GetMP3Stream> threads=new ArrayList<GetMP3Stream>();
  // start a thread for each MP3 source
  for(String part: synthText){
    Thread thr=new GetMP3Stream(part);
    thr.start();
    threads.add(thr);
  }
  // collect opened input streams in a list
  List<InputStream> streams=new ArrayList<InputStream>();
  for(GetMP3Stream thr: threads){
    thr.join();
    streams.add(thr.res);
  }
  //Concatenate all input streams 
  return  new java.io.SequenceInputStream(streams);
}

class GetMP3Stream extends Thread {
 String url;
 InputStream res;
 GetMP3Stream (String url) {
   this.url=url;
 }
 public void run() {
   res=getMP3Data(url);
 }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM