2016/07/06

[java]CountDownLatchはawait()前にcountDown()されることも考慮しよう

非同期処理の待ち合わせに、CountDownLatchを使っていた。
Effective Javaにも書いてあったので、だいたいそうするのだろう。

 

これをタイムアウト有りでawait()させていたのだが、ときどきタイムアウトが発生していることに気付いた。
通信なので相手とのタイミングはときどき変わるものの、タイムアウトするような要素はない。
なぜだ。。。

 

今回、await()やcountDown()でチェックしたいものがあったので、それらをラップしたメソッドを作っていた。
で、await()させるほうのメソッドでCountDownLatchをnewし、非同期で終わったときにcountDown()させるようにしていた。
一応、異常時にawait()せずに非同期処理だけが動くパターンがあるので、その場合はcountDown()させないようにしていた。

そしたら、await()が呼ばれる前に非同期処理の方が先に完了していたのだ。
もしcountDown()をそこで呼んでいればawait()はtrueで終わるのだけど、異常時と同じルートを通ったためcountDown()せず。。。

 

いや、言い訳だけすると、これでも非同期処理が先に終わるのは考慮したつもりだったのだよ。
ただなんとなく、Javaのスレッドってメソッド単位とかでやってくれるんじゃないの、などと思っていたのだ。
適当は、いかんね。

 

対処は、非同期処理を呼ぶ前にCountDownLatchをnewさせ、異常ルートでもcountDown()を呼ぶようにした、だ。
カウントダウンする準備さえ整えておけば、怖いものではない。

 

ただ、そこに行くまでが紆余曲折してね。。。
スレッドだから、ディスパッチ禁止させようとしてメソッドをsynchronizedにしてしまい、デッドロックしたとかね。。。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。