Java開発メモ 2010/10/14
Counterクラスというのを作って、複数スレッドからadd()してカウンタをインクリメントする。getCount(double sec)で過去sec秒にadd()された回数を返したい。add()、getCount()とも毎秒5万回は呼びたいけど効率のよい方法が思いつかない
2010-10-14 13:07:12LinkedBlockingQueue案:各スレッドがput()しつつメンテナンススレッドがsec経過したものをtake()しまくる、カウンタはsize()でとる → take()間に合わないだろう常考
2010-10-14 13:18:22@sh2nd 時刻はSystem.currentTimeMillis()で取得して、切り下げて秒にする。で、ConcurrentMapのKeyに時刻、valueにAtomicIntegerをputしてカウントするのかな。
2010-10-14 13:31:00@sh2nd だけど、毎秒5万回だとMapのget処理に時間がかかりそうなので、毎回ConcurrentMapにアクセスしないように工夫したほうがいいのかもしれない。でもsynchronizedかかるなら一緒か?やってみないとわからないなぁ
2010-10-14 13:32:16DB的にはINSERT、DELETE WHERE t < NOW() - 1、COUNT(*) WHERE t >= NOW() - 1、というオペレーションだと考えれば、DELETEとCOUNT(*)をO(1)でやるのはあきらめざるを得ないのかなー
2010-10-14 13:44:42. @royzumi getCount()の引数は整数でよいけど、プログラム開始5.456秒にgetCount(1)したら4.456~5.456秒の間にincされた回数を返してほしい
2010-10-14 13:50:491ミリ秒に配列をちぎって管理すれば、add()とexpireされたデータの削除は簡単だけど、getCount()で1,000要素にアクセスしないといけない
2010-10-14 14:01:48@sh2nd 配列を使う方法もある。Countする最大の時間。たとえば5000ミリ秒だと5000個分のAtomicIntegerの配列を作るとか。カウンターリセットタイミングが難しいけど。
2010-10-14 14:06:17@tamtam180 あー、1ミリ秒ごとにtotal += count[i] - count[i - 1000]すればいいですね。ありがとうございます!
2010-10-14 21:22:16@tamtam180 100ミリ秒おいてイベントが発生したときにサイクルバッファの該当100要素をどのスレッドが0クリアするのか、とかがめんどくさいですね(´・ω・`)
2010-10-14 21:30:33マルチスレッドでSystem.nanoTime()をすると、時間が巻き戻ることがあるってことなのかもしかして。CPUコアによって時計が違う
2010-10-25 11:17:51うーんこれか。nanoTimeはかならず単調増加すると思って書いたプログラムがマルチスレッドにしたとたんバグった http://www.02.246.ne.jp/~torutk/javahow2/time.html#doc1_id95
2010-10-25 11:19:17