2

クライアント側のコードの一部をベンチマークしようとしているプロジェクトに取り組んでいます。

Multithreading programそのために、複数のスレッドを生成し、各スレッドが特定の期間実行されるを書きました。プログラムが終了した後logHistogramInfo() method、finally ブロックを呼び出してhistorgram informationfor を出力します。これにより、クライアント コードがどのように動作したかがわかります。 .

以下は、複数のスレッドを生成し、finally ブロックで呼び出しているコードですlogHistogramInfo method

public static void main(String[] args) {

    try {

        readPropertyFiles(args);

        //create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(noOfThreads);

        long startTime = System.currentTimeMillis();
        long endTime = startTime + (durationOfRun * 60 * 1000);

        for (int i = 0; i < threads; i++) {
            service.submit(new CassandraReadTask(endTime, columnFamilyList));
        }

        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
    } catch (InterruptedException e) {

    } catch (Exception e) {

    } finally {
        logHistogramInfo();
    }

    LOG.info("All threads are finished");
}

以下は私のヒストグラム方法です -

private static void logHistogramInfo() {

    int[] definition = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 };
    long[] buckets = new long[definition.length];

    System.out.println("Milliseconds           Number");
    SortedSet<Long> keys = new TreeSet<Long>(CassandraTimer.histogram.keySet());
    for (long key : keys) {
        Long value = CassandraTimer.histogram.get(key);
        System.out.println(key + "                      " + value);
    }

    //Histogram information
    for (Long time : CassandraTimer.histogram.keySet()) {
        for (int i = definition.length - 1; i >= 0; i--) {
            if (time >= definition[i]) {
                buckets[i] += CassandraTimer.histogram.get(time);
                break;
            }
        }
    }
    for (int i = 0; i < definition.length; i++) {
        String period = "";
        if (i == definition.length - 1) {
            period = "greater than " + definition[i] + " ms";
        } else {
            period = "between " + (definition[i] + 1) + " and " + definition[i + 1] + " ms";
        }
        LOG.info(buckets[i] + " came back " + period);
    }
}

問題文:-

私にとってはすべてがうまくいっています。唯一の問題は、プログラムを実行している場合10hours 、プログラムが終了するまで待つ必要があるとします。たった10時間後に、結果がどうなるかがわかります。

プログラムの実行中に結果を見ることに興味があります。プログラムがどのように動作しているかを理解するためだけに。10時間待ってから結果を見たくありません。

今私が考えているのは、10 hours10分または20分ごとにプログラムを実行しているとします(設定可能である必要があります)。呼び出しlogHistogramInfo() methodて結果を表示する必要があります。

プログラムが終了するとlogHistogramInfo() method、finally ブロックで が自動的に呼び出されます。ですから、最終的に全体像をつかむことができます。しかし、20 分ごとに、プログラムが終了するのを待つのではなく、プログラムがどのように動作しているかを確認できます。これは可能ですか?

どの例も非常に役立ちます。

更新されたコード:-

以下のコードでは、数分ごとにログが出力されません。デバッグして、try ブロック内にブレークポイントを配置しようとしましたが、そのブレークポイントにもヒットしていません。理由はありますか?

// queue some tasks
long startTime = System.currentTimeMillis();
long endTime = startTime + (durationOfRun * 60 * 1000);

for (int i = 0; i < threads; i++) {
        service.submit(new CassandraReadTask(endTime, columnFamilyList));
}

service.shutdown();

loggingAfterEveryXMinutes();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);


/**
 * This is a simple which will call the logHistogramInfo method after every X Minutes
 */
private static void loggingAfterEveryXMilliseconds() {
    new Thread() {
        public void run() {
            while (true) {
                try { 
                    Thread.sleep(loggingEveryXMilliseconds); 
                }
                catch (InterruptedException ex) {

                }
                logHistogramInfo();
            }
        }
    }.start();      
}
4

1 に答える 1

1

ここには 2 つの選択肢があります。

1) 「更新期間」を事前に設定する

これは、すでに特定されているソリューションです。ロギングを行うために、次のように追加のスレッドを設定するだけです。

new Thread() {
    public void run() {
        while (true) {
            try { Thread.sleep(numMinutes * 60 * 1000); }
            catch (InterruptedException ex) { }
            logHistogramInfo();
        }
    }
};

2) ヒストグラム情報をオンデマンドで取得できるフックを提供する

これを行うにはいくつかの方法がありますが、最も一般的な方法は、ブラウザーからアクセスして情報をレンダリングできる HTTP サーバーをセットアップすることです (または、単にプログラムにヒストグラム情報をログ ファイルにレンダリングさせることができます)。 HTTP サーバーがヒットします)

Apache Commons は、この種のものをすばやくセットアップするのに役立ちますが、実際にはそれほど多くはありません。

new Thread() {
    public void run() {
        ServerSocker serverSocket = new ServerSocket(12345);
        while (true) {
            Socket socket = serverSocket.accept();
            PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream());
            pw.println("Histogram Info");
            // Print histogram info
            pw.flush();  pw.close();
            socket.close();
        }
    }
}
于 2013-04-22T01:09:25.287 に答える