2

ファントムを使用する場合、db 呼び出しで次のパターンに従うことはどれほど危険ですか。

Await.result(dbOperationFut, 30.seconds)

これはファントム固有のものではありませんが、使用されているのは scala ドライバーです。

GC の一時停止が x 秒以上続く可能性があるため、このパターンにはうんざりしています。GC の一時停止を考えると、安全な秒数は何秒ですか?

私は個人的に for-comp を使用し、このようにブロックしないことを支持していますが、これが本当に悪い習慣なのか、それとも問題ないのかを知りたいだけです。

コンテキスト: これは、akka ベースのアプリケーション (akka、akka http) 用です。

考え?

4

1 に答える 1

4

Await.result に注意

これは Akka アプリと Play アプリの両方に適用されることに注意してください

Await.result絶対に必要な場合にのみ、慎重に使用してください。

Await.result指定された期間まで、実行中のスレッドをブロックします。スレッドをブロックすると、貴重な計算リソースが浪費されます。そのスレッドは、新しいリクエストの処理やアルゴリズムでの数値処理などの有用な計算を実行できなくなるためです。

Await.resultそのため、できるだけ使用を避けてください。

しかし、いつ (Await.result) を使用するのでしょうか?

を使用する典型的な使用例の 1 つを次に示しAwait.resultます。

メイン スレッドを含むプログラムを作成し、メイン スレッド内のすべての計算が非同期であるとします。ここで、メイン スレッド内で非同期計算を開始します。プログラムが実行を停止し、非同期計算の結果が表示されない場合、非同期計算が終了するまでメインスレッドの存在を停止する必要があります。

アプリケーションが実行を開始すると、main() を実行するジョブを持つ非デーモン スレッドが 1 つあります。JVM は、非デーモン スレッドが完了するまで終了しません。

object Main {
 def main(args: Array[String]): Unit = {
  import scala.concurrent.Future
  import scala.concurrent.duration._

  val f = Future { //do something }
  //stop main thread till f completes
  Await.result(f, 10 seconds)
 }
}

Future は、実行にデーモン スレッドを使用します。そのため、デーモン スレッドは JVM のシャットダウンを停止できません。そのため、デーモン以外のスレッドが実行されている場合でも、JVM はシャットダウンします。

f上記の場合、メインスレッドが終了して計算が停止しない場合、計算が完了するまでメインスレッドを停止 (ブロック) する以外に方法はありません。

ほとんどの場合、使用する必要はなく、 and を使用したAwait.result単純なFuture構成で十分です。mapflatMap

Await.result を使用するリスク (一般的にすべてのブロック コード)

イベントベースのモデルでスレッドが不足している

イベント ベースのモデルでは、戻るのに時間がかかるブロック コードがあると、すぐにスレッドが不足してしまいます。playframework では、ブロッキング呼び出しによってアプリケーションのパフォーマンスが低下する可能性があり、スレッドが不足するとアプリが非常に遅くなります。

非イベント ベースのモデルでのメモリ不足

要求モデルごとのスレッド。終了/復帰に時間がかかるブロッキングコールがある場合。

ケース 1: スレッド プールを固定している場合、アプリケーションでスレッドが不足する可能性があります。

ケース 2: スレッド プールが動的に拡大している場合、アプリケーションはコンテキスト切り替えのオーバーヘッドが多すぎます。また、メモリ内のブロックされたスレッドが多すぎるため、メモリが不足します。

すべての場合において、何らかの IO やその他のイベントを待機することを期待して、有用な作業は行われません。

于 2016-11-25T09:52:15.347 に答える