-1

Jsoup (1.6.2) を使用して特定の Web サイトのテキストをダウンロードする小さなコードを作成しました。

public String readPage(String url) {

    try {

        long start = System.currentTimeMillis();
        String text = Jsoup.connect(url).timeout(10000).get().html();
        System.out.println(System.currentTimeMillis() - start);
        return text;
    }
    catch (IOException e) {

        // we need to do this because the log file is flooded with useless error messages 
        if ( e.getMessage().contains("Unhandled content type") ||
             e.getMessage().contains("Premature EOF") ||
             e.getMessage().contains("Read timed out") ||
             e.getMessage().contains("403 error loading URL") ||
             e.getMessage().contains("404 error loading URL") ||
             e.getMessage().contains("405 error loading URL") ||
             e.getMessage().contains("500 error loading URL") ||
             e.getMessage().contains("503 error loading URL") ) {

            logger.debug(String.format("Error crawling website: %s", url));
        }
        else logger.error(String.format("Error crawling website: %s", url), e);
    }

    return "";
}

このメソッドは、スレッドのリスト内で開始します。各スレッドは、1 つの Web サイトのダウンロードを担当します。私の見解では (これは明らかに間違っています)、Jsoup は例外をスローする必要があるため、すべての system.out は 10000 未満の数値を表示する必要があります。ただし、stdout に 100k を超えるタイムスパンがある場合はそうではありません。

これはどのように可能で、何が間違っていますか?

乾杯ダニエル

4

2 に答える 2

1

これは私を驚かせません。開始時刻から終了時刻までの間には、さまざまなことが起こっています。接続は締め切り前に行われた可能性があり、ダウンロードの速度によっては (特に一度に複数のことを行っているため)、終了時間が簡単に締め切りを超えてしまう可能性があります。

あなたのコメント:

申し訳ありませんが、これについて詳しく説明していただけますか?

次の行があります。

String text = Jsoup.connect(url).timeout(10000).get().html();

一度に複数のスレッドから呼び出されます。それらすべてがすばやく接続するシナリオを想像してみてください。ただし、すべてのスレッドが情報をダウンロードして処理するには時間がかかります。特に、多くのスレッドがすべて同じリソースを求めて競合している場合はそうです。

于 2012-05-16T19:05:52.483 に答える
1

thread 1実行long start = System.currentTimeMillis()され、システム スケジューラがこの最初のスレッドを停止し、2 番目のスレッドを開始するとします。2 番目のスレッドが呼び出さlong start = System.currentTimeMillis()れ、3 番目のスレッドがそのコードを呼び出すために停止します。

これは不確定です。システム スケジューラは、すべてのスレッドが完了した後に実行中の n 番目のスレッドを割り当てることができます。System.out.println は、すべてのスレッドの期間と同じ長さにすることができます。

タイムアウトは機能しますが、スレッド化が問題です。

于 2012-05-16T19:13:58.453 に答える