1

URLがデータベースに保存されているWebサイトのHTMLコードを同時にダウンロードしようとしています(約300万のエントリ)。
マルチスレッド技術を使用する必要があることは明らかですが、Java でそれを行う方法に問題があります。

マルチスレッドなしでそれを行う方法は次のとおりです。

final Connection c = dbConnect(); // register jdbc-driver and establish connection
checkRequiredDbAndTables();  // here we check the existence of the Db and necessary tables

try {
    // now get list of urls from the db
    String sql = "select id, website_url, category_id from list_of_websites";
    PreparedStatement ps = c.prepareStatement(sql);
    ResultSet rs = ps.executeQuery();

    while (rs.next()) {
    // column numeration in ResultSet is from 1 !
        final long id = rs.getInt(1);   // get website id
        final String url = rs.getString(2);   // get website url

        System.out.println("Category: " + rs.getString(3) + " " + id + " " + url);

        if ( isValidURL(url) && connectionOK(url) ) {
        // checked url syntax and connection 
            String htmlInPage = downloadHTML(url);
            if (!htmlInPage.equals("")) {
            // add result to db
                insertDataToDb( c, id, htmlInPage);
             }
        }
    }
    rs.close();
 } catch (SQLException e) {
        e.printStackTrace();
 }
    closeConnection(c);  // database connection closed

関数donloadHTMLJSoupライブラリを使用して主な作業を行います。

私の仕事は一種の「生産者消費者問題」のような気がします。このような方法で表現できると思います。N 個のリンクを含むバッファーがあります。一部のプロセスはそこからリンクを取得し、HTML をダウンロードします。プロセスは、空になったときに新しい URL を db からバッファにロードすることを目的としています。
しかし、私はそれを行う方法がまったくわかりません。ThreadsExecutorService提供について聞いたことがありThreadPoolsますが、それは私にとって本当に混乱しています。

4

2 に答える 2

0

メインスレッド:

  • X の「ダウンロード」スレッドを開始する
  • 質問に示されているクエリを実行します。for各レコード:
    • クエリからデータをArrayBlockingQueue
  • データの終わりマーカーをキューに追加する
  • スレッドが停止するのを待ちます (オプション)
  • から戻るmain

スレッドをダウンロード:

  • キューからデータを取得します。whileデータ終了マーカーではありません:
    • HTMLをダウンロード
    • HTML をデータベースに挿入する
  • 他のスレッドが見つけられるように、データの終わりマーカーをキューに戻します
  • スレッドを終了
于 2015-09-12T16:41:07.363 に答える