Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从URL存储原始HTML内容,然后从内存获取InputStream(不使用连接)_Java_Multithreading_Http_Producer Consumer - Fatal编程技术网

Java 从URL存储原始HTML内容,然后从内存获取InputStream(不使用连接)

Java 从URL存储原始HTML内容,然后从内存获取InputStream(不使用连接),java,multithreading,http,producer-consumer,Java,Multithreading,Http,Producer Consumer,我有一个涉及多线程的棘手问题。我所做的是使用线程池(ExecutorService),该线程池负责打开连接并将它们放入LinkedBlockingQueue 到目前为止,我使用了: //run method in "getter threads" public void run() { try { URL url = new URL(url_s); //url_s is given as a constructor argument //if I am correc

我有一个涉及多线程的棘手问题。我所做的是使用线程池(
ExecutorService
),该线程池负责打开连接并将它们放入
LinkedBlockingQueue

到目前为止,我使用了:

//run method in "getter threads"
public void run() {

    try {

    URL url = new URL(url_s); //url_s is given as a constructor argument

    //if I am correct then url.openStream will wait until we have the content
    InputStream stream = url.openStream();

    Request req = new Request(); //a class with two variables:
    req.html_stream = new InputSource(stream);
    req.source = stream;

    //this is a class variable (LinkedBlockingQueue<Request>)
    blocking_queue.put(req);

    } catch  (Exception ex) {
    logger.info("Getter thread died from an exeption",ex);
    return;
    }
}
其中eat_数据调用接受InputSource的外部库。该库使用一个单例实例进行处理,因此我不能将此步骤放在“getter”线程中

当我为少量数据测试这段代码时,它工作得很好,但当我为它提供数千个URL时,我开始遇到实际问题。要找出到底是什么问题并不容易,但我怀疑连接在使用者线程到达它们之前就超时了,有时甚至会导致死锁

我这样实现它是因为从url.openStream()到InputSource非常容易,但我意识到我必须将数据存储在本地才能工作


如何从url.openStream()获取某个对象,我可以将其存储在
LinkedBlockingQueue
(内存中的所有数据)中,当我的消费者线程有时间处理它时,我可以将其转换为输入或产生?

您可以将url的内容复制到
ByteArrayOutputStream
并关闭url流。然后将
ByteArrayInputStream
存储在队列中

伪代码:

InputStream in = null;
try {
    in = url.openStream();
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    IOUtils.copy(in, buffer);

    ByteArrayInputStream bin = new ByteArrayInputStream(buffer.toByteArray());
    queue.put(bin);
}
参考资料:


  • 就我个人而言,我不会打开连接,直到你打开它们。我将URL:传递给
    请求
    对象,并让它在需要时打开连接。这还意味着您可以控制连接的关闭(您打开了它,您负责关闭它)。IMHO@MadProgrammer但是,这样是否就不需要等待连接的回复了?这就是我使用多线程的原因。使用“getter”线程是为了使处理器线程不需要等待IO(例如http响应)。不,这样的线程是为了减少活动连接(和资源)的数量,否则会消耗这些连接。仅在需要时打开连接,完成后关闭连接。在Windows上,您很快就会遇到问题,因为它对您可以打开的活动连接的数量有一个非常严格的上限,并且正如您所指出的,您无论如何都会遇到超时。我个人会使用
    请求
    打开、阅读、存储和关闭URL中的内容。然后我会把它放在一个队列中,等待处理器线程出现,并在它可以自由处理时进行处理。。。
    InputStream in = null;
    try {
        in = url.openStream();
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        IOUtils.copy(in, buffer);
    
        ByteArrayInputStream bin = new ByteArrayInputStream(buffer.toByteArray());
        queue.put(bin);
    }