0

データベースから 50000 個のデータを取得し、arraylist に保存しました。arraylist を半分に分割し、250000 が ArrayList1 (偶数行) に格納され、他の 25000 ArrayList2 (奇数行) が格納されているとします。

ここで、一度に 50,000 件のレコードすべてが処理されるようにこれらを処理するために、マルチスレッドを使用する必要があります。主な目的は、トランザクションを高速化することです。

問題はuserList、重くなりすぎて時間がかかることです。

ExecutorService を実装して高速化するにはどうすればよいですか?

できるだけ早くあなたの提案を受け取ることを望んでいます。

List<String[]> userList = new ArrayList<String[]>();
void getRecords()
{
    String [] props=null;
    while (rs.next()) {
        props = new String[2];
        props[0] = rs.getString("useremail");
        props[1] = rs.getString("active");
        userList.add(props);
        if (userList.size()>0) sendEmail();   
    }
}

void sendEmail()
{
    String [] user=null;
    for (int k=0; k<userList.size(); k++) 
    { 
        user = userList.get(k);
        userEmail = user[0];         
        //send email code
    }
}

前もって感謝します。

4

4 に答える 4

2

スレッドごとに ArrayList を作成します。そうすれば、各スレッドは 1 つのリストのみを読み取るため、マルチスレッドの問題は発生しません。

ExecutorService service = ...


List<Work> workList = ...

int blockSize = (workList.size() + threads - 1)/threads;
for(int i = 0; i < threads;i ++) {
   int start = i * blockSize;
   int end = Math.min((i + 1) * blockSize, workList.size());
   final List<Work> someWork = work.subList(start, end);
   service.submit(new Runnable() {
       public void run() {
           process(someWork);
       }
   });
}

任意の数のスレッドを使用できますが、パフォーマンスが向上する最小の数を使用することをお勧めします。

于 2012-09-06T10:52:52.240 に答える
2

より簡単なアプローチがあります: 生産者と消費者です。すべての項目を 1 つのリストに残して、データ項目をカプセル化する処理タスクを定義します。

class Task implements Runnable {
     private Object data;

     public Task(Object data) {
         this.data = data;
     }

     public void run() {
        // process data
     }
}

スレッド プールを作成し、タスクを 1 つずつフィードします。

ExecutorService exec = Executors.newFixedThreadPool(4); // 4 threads
for(Object obj: itemList) {
    exec.submit(new Task(obj));
}

exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

これで、スレッドが前のタスクを完了するときにオンデマンドで作業を実行するため、並列実行と負荷分散 (!!!) が実現します。配列を連続したセクションに分割すると、この保証はありません。

于 2012-09-06T10:56:54.543 に答える
0

リストを 2 つのリストに分割した理由がわかりません。それらを 1 つにまとめて、2 つのスレッドを実行してみませんか? 1 つは偶数行を処理し、もう 1 つは奇数行を処理します。

とにかく、Java Executorフレームワークを調べてください。ジョブを簡単に作成し、実行するために送信することができます (スレッド プールの使用、スケジュール設定など)。エグゼキュータ フレームワークが任意の数のスレッドを処理できることを考えると、ワークロードをよりインテリジェントに (おそらく「n」個の要素のサブリストに) 分割し、(ジョブ/スレッドの数を変更することによって) 特定のシナリオでどの構成が最も速く実行されるかを判断します。 .

于 2012-09-06T10:52:42.653 に答える
0

Queuea の代わりに aを使用します。Listおそらく aConcurrentLinkedQueueです。これはスレッドセーフであり、異なるスレッドからの同時アクセスを許可する必要があります。

于 2012-09-06T10:57:40.457 に答える