Javaのドリップは、スレッドが実行メソッドを停止させる

  1. Thread.yield()メソッドの機能は
  
  、現在実行中のスレッドオブジェクト中断し、他のスレッドを実行することです。yield()がすべきことは、現在実行中のスレッドを実行可能な状態に戻して、同じ優先順位を持つ他のスレッドが実行される機会を得られるようにすることです。したがって、yield()を使用する目的は、同じ優先順位のスレッド間で適切にローテーションできるようにすることです。ただし、実際には、譲歩のスレッドもスレッドスケジューラによって再度選択される可能性があるため、yield()が譲歩の目的を達成するという保証はありません。結論:yield()によってスレッドが待機/スリープ/ブロック状態になることはありません。ほとんどの場合、yield()はスレッドを実行状態から実行可能状態に
  
  移行させますが、効果がない場合があります。2.Thread.sleep():
  
  現在のスレッドを少なくとも何ミリ秒間スリープさせます(指定された時間より前であってもかまいません)中断されました)。
  
  3. Join()メソッド:
  
  スレッドが参加するスレッドが完了するまで、現在のスレッドが実行を停止することを確認します。ただし、参加するスレッドが存続しない場合、現在のスレッドを停止する必要はありません。スレッドmyMainThreadで別のスレッドオブジェクトmyThreadのjoinメソッドを呼び出します。つまり、myMainThreadスレッドは、myThreadのスレッドが完了するのを待ってから実行する必要があります。この時点で、myThreadが挿入され、招待が解放される前に完了する必要があります。
  
  結合(ミリ秒単位)を使用している場合、パラメーターはmyMainThreadスレッドの最長の待機時間を示します。この値の後は、待機しません
  
  。4.いくつかの特別な状況により、スレッドが実行状態を終了する場合があります
  
  。1.スレッドのrun()メソッドできました。
  
  2.オブジェクト(スレッドではない)でwait()メソッドを呼び出します。
  
  3.スレッドはオブジェクトのロックを取得できません。オブジェクトのメソッドコードを実行しようとしています
  
  4.スレッドスケジューラは、現在の実行状態を実行可能な状態に移動することを決定できるので、別のスレッドが理由なく実行できるようになります。

  ほとんどすべてのプログラミング言語は「乱数を生成する」メソッドを提供します。つまり、このメソッドを呼び出すと数値が生成されます。どのような数値が生成されるかは事前にわかりません。たとえば、.Netで次のコードを記述します:
  
  Random rand = newRandom();
  
  Console.WriteLine(rand.Next());
  
  実行後結果は次のとおりです:
  
  bubuko.com、Bubuko
  
  Next()メソッドを使用して乱数を返します。あなたが実行する同じコードと私の結果は異なる可能性が高く、私の複数の実行の結果も異なる可能性があります。これは乱数です。
  
  1.トラップは
  
  一見単純なように見えますが、使用するとトラップが発生します。次のコードを記述して、100個の乱数を生成します:
  
  for(int i = 0; i <100; i ++)
  
  {
  
  Random rand = new Random();
  
  Console.WriteLine(rand.Next());
  
  }
  
  bubuko.com、ぶぶバックルが
  
  おかしい生成される「乱数」は連続したものが多い「乱数」とは?誰かがforループの外に「put new Random()」を指定しました:
  
  Random rand = newRandom();
  
  for(int i = 0; i <100; i ++)
  
  {
  
  Console.WriteLine(rand.Next());
  
  }
  
  実行結果:
  
  bubuko.com、
  
  それは本当にうまくいきます!
  
  2.なぜですか?
  
  これは、コンピュータでの「乱数」生成の原則から始まります。コンピュータは非常に厳密であり、特定の入力条件下では、生成される結果は一意に決定され、実行されるたびに変わることはありません。それでは、ソフトウェアを使用して、一見不明確な乱数を生成する方法を教えてください。
  
  乱数を生成するアルゴリズムは多数ありますが、最も単純で最も一般的に使用されるのは「線形合同法」です。n+ 1番目の数=(n番目の数* 29 + 37)%1000、%は「残りを見つける」オペレーター。私のような多くの人が数式を見ると頭痛がします。コードで説明しましょう。MyRandは、乱数を生成するカスタムクラスです:
  
  クラスMyRand
  
  {
  
  private int seed;
  
  public MyRand(int seed)
  
  {
  
  this.seed = seed ;
  
  }
  
  public int Next()
  
  {
  
  int next =(seed * 29 + 37)%1000;
  
  seed = next;
  
  return next;
  
  }
  
  }
  
  次のように呼び出されます:
  
  MyRand rand = newMyRand(51);
  
  for(int i = 0; i < 10; i ++)
  
  {
  
  Console.WriteLine(rand.Next());
  
  }
  
  実行結果は次のとおりです。
  
  bubuko.comでは、Bubuko
  
  によって生成されたデータは「ランダム」に見えますか?このコードの簡単な説明:MyRandのオブジェクトを作成し、コンストラクターが数値51を渡します。この数値はシードに割り当てられ、Nextメソッドが呼び出されるたびに、(seed * 29 + 37)%1000に従って、乱数が計算されます、この乱数をシードに割り当て、生成された乱数を返します。次にNext()を呼び出すと、シードは51ではなく、前回生成された乱数なので、生成されたコンテンツは常に「ランダム」であるように見えます。残りの予算「%1000」の目的は、生成された乱数が1000を超えないようにすることです。
  
  もちろん、実行しても、実行するたびに、出力結果は同じ乱数になります。これは、与えられた初期データ51に従って、以下で生成されるすべての「乱数」を順番に推測できるためです。 。この初期データ51は「乱数シード」と呼ばれ、この一連の516、1、66、951、616 ...番号は「乱数シーケンス」と呼ばれます。51を52に変更すると、そのような結果になります
  
  。bubuko.com、Bubu buckle
  
  第三に、家主は良い人、Guiqiuシード
  
  です。プログラムを実行するたびに、どのようにして異なる「乱数シーケンス」を作成できますか?プログラムを実行するたびに時刻が異なる可能性があるため、現在の時刻を「乱数シード」として使用できます
  
  MyRand rand = newMyRand(Environment.TickCount);
  
  for(int i = 0; i <10; i ++)
  
  {
  
  Console.WriteLine(rand.Next());
  
  }
  
  Environment.TickCountは、「システムが起動してから経過したミリ秒数」です。このように、Environment.TickCountはプログラムが実行されるたびに同じになる可能性は低く(1ミリ秒以内にプログラムを2回手動で開始できます)、毎回生成される乱数は異なります。
  
  bubuko.com、布ボタン
  
  もちろん、新しいMyRand(Environment.TickCount)をforループに配置した場合
  
  :?
  
  for(int i = 0; i <100; i ++)
  
  {
  
  MyRand rand = newMyRand(Environment.TickCount);
  
  Console .WriteLine(rand.Next());
  
  }
  
  bubuko.comでは、布ボタンの
  
  実行結果が「多数連続」になるため、原理は非常に単純です。for ループの本体がすばやく実行されるため、環境が実行されるたびに.TickCountは前回と同じである可能性が高いです(2行の単純なコードはミリ秒のイベントほど長くはかかりません)。今回の「乱数シード」は最後の「乱数シード」と同じであるため、Next()が生成されます。最初の「乱数」は同じです。「-320」から「-856」への変更は、「-856」への実行時に1ミリ秒の時間が経過したためです。
  
  第4に、各言語の実装
  
  .NetのRandomクラスには、int型パラメーターを持つコンストラクターがあることがわかります。public
  
  Random(int Seed)
  
  私たちが書いたMyRandのような「乱数シード」を受け入れることです。前に呼び出したパラメーターなしのコンストラクターは、Environment.TickCountクラスをRandom(int Seed)に渡すことによって作成されました。コードは次のとおりです:
  
  public Random():this(Environment.TickCount)
  
  {
  
  }
  
  これで、最初の疑問がようやくわかりましたあまりにも。
  
  同じ理由で、C / C ++で10個の乱数を生成することは、次のように呼び出さないでください:
  
  int i;
  
  for(i = 0; i <10; i ++)
  
  {
  
  srand((unsigned)time(NULL));
  
  printf( "%d \ n "、rand());
  
  }
  
  代わりに:
  
  srand((unsigned)time(NULL)); //現在の時刻を「乱数シード」として設定し
  
  ますint i;
  
  for(i = 0; i <10; i ++ )
  
  {
  
  printf( "%d \ n"、rand());
  
  }
  
  5番目の「エキゾチックな」Java
  
  Java学習者は質問をするかもしれません。Javaの下位バージョンでは、次の使用法は.Net、C / C ++のようになります同じ方法で同じ乱数を生成し
  
  ます:?
  
  For(int i = 0; i <100;
  

  

  
  System.out.println(rand.nextInt());
  
  }
  
  低レベルJavaのRandクラスのパラメーターなしのコンストラクターの実装も現在の時刻をシードとして使用するため:
  
  public Random(){this(System.currentTimeMillis()); }
  
  しかし、このようなJava1.8などのJavaの高いバージョンでは、上記「エラー」コードの実行は問題ありません:
  
  bubuko.com、豊胸手術バックル
  
  なぜ?このランダムなパラメータのないコンストラクタの実装コードを見てみましょう:
  
  public Random()
  
  {
  
  this(seedUniquifier()^ System.nanoTime());
  
  } <br>
  
  private static long seedUniquifier(){
  
  for(;;){
  
  long current = seedUniquifier.get();
  
  long next = current * 181783497276652981L;
  
  if(seedUniquifier.compareAndSet(current、next))
  
  return next;
  
  }
  
  }
  
  privatestaticfinal AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
  
  ここでは、現在の時間を使用して「乱数シード」を行うのではなく、System.nanoTime()ナノ秒単位の時間と、コンストラクターへの最後の呼び出しに従って原子量AtomicLongを使用して計算された数値とのXORを使用しています。 。このコードの説明については、この記事「Javaソースコードからの復号化乱数ジェネレーター(2)-線形合同アルゴリズム」を参照してください。この記事
  
  のコアは、静的変数AtomicLongを使用して、ランダムコンストラクターが呼び出されるたびに記録することです。使用するシードは、次にRandomコンストラクターが呼び出されるときと同じであってはなりません。
  
  6.同時実行性の高いシステムでの問題
  
  以前に、システム時刻を「乱数シード」として使用する乱数ジェネレータの場合、複数の乱数を生成する場合、それを回避するために「乱数シード」を共有する必要があることを分析しました。短時間で乱数を生成します。しかし、問題に注意を払うも、以下の方法によって生成されたサーバ認証コード上のWebサイトなどの一部の高並行システム、中:
  
  ランダム新しい新しいRANDはランダム()=;
  
  のInt rand.Nextコードを=();
  
  ときウェブサイトの同時実行量が多い場合、ミリ秒以内に確認コードを要求する多くの個人が存在する可能性があり、これらの個人が要求する確認コードが繰り返され、システムに潜在的な脆弱性がもたらされます。
  
  もう1つの例は、今日見た記事「ランダムはランダムではない:オンラインポーカーゲームからの教訓」です。「乱数ジェネレーターのシードはサーバークロックに基づいているため、ハッカーはプログラムをサーバーに接続するだけです。クロックの同期により、発生する可能性のある順序の乱れを200,000に減らすことができます。その時点で、ハッカーは5枚のカードを知ると、リアルタイムで200,000の順序の乱れの可能性をすばやく検索して、ゲームの種類を見つけることができます。ハッカーが2枚のカードと3枚の一般的なカードを手に入れたら、ターンカードとリバーカード、および他のプレイヤーのカードにどのカードが入るかを推測できます。
  
  この状況にはいくつかの解決策があります
  
  Randomオブジェクトをグローバルインスタンス(静的)として使用します。Javaのランダムはスレッドセーフです(内部ロックあり)。.Netのランダムはスレッドセーフではなく、ロックが必要です。ただし、ロックすると処理速度が遅くなるという問題があります。また、初期シードが決定されているため、攻撃者は取得した乱数列に基づいて「乱数シード」を推測する可能性があります。
  
  生成されたGuidの値は毎回異なるため、インターネット上のいくつかの記事では、Guidを作成してシードとしてHashCodeまたはMD5値を計算できるとしています:新しいRandom(Guid.NewGuid().GetHashCode())。しかし、Guidの生成アルゴリズムは決定論的であり、十分な条件下で予測可能であるため、生成される乱数も予測できます。もちろん、それは私の推測であり、理論的な証明はありません。
  
  「真の乱数ジェネレータ」を使用して、分解について次のセクションを見てください。
  
  7.真の乱数ジェネレーター
  
  以前の分析によれば、これらのいわゆる乱数は実際には「ランダム」ではなく、単にランダムに見えるため、「疑似ランダムアルゴリズム」と呼ばれています。ランダム要件が高い場合には、物理​​ハードウェアを使用して、物理ノイズ、宇宙線、量子崩壊などの実際のランダム物理パラメータを収集し、実際の乱数を生成します。
  
  もちろん、「乱数ジェネレータ」ハードウェアを追加せずに乱数を生成することを考えている賢い人もいます。私たちがコンピューターを操作するとき、マウスの動きとキーボードの入力は予測できません。また、外部の世界がコンピューターに実行するプロセス、処理するファイル、ロードするデータなどを指示するときも予測できません。読み取りと書き込みの動作とメモリ使用量の変化も予測できません。したがって、この情報が乱数シードとして収集される場合、生成される乱数は予測できません。
  
  "/ Dev / random"はLinux / Unixで使用できます
  
  Windowsでは、システムのCryptGenRandom()関数を呼び出すことができます。これは、主に現在のプロセスID、現在のスレッドID、システム起動後のTickCount、現在の時刻、QueryPerformanceCounterによって返される高性能カウンター値、ユーザー名、コンピューター名、CPUカウンター値などに基づいています。計算を待ちます。「/ dev / random」のように、CryptGenRandom()の生成速度は比較的遅く、比較的大きなシステムリソースを消費します。
  
  もちろん、(System.Security.Cryptography名前空間の下にある)RNGCryptoServiceProviderクラスを使用して、.Netの下で真の乱数を生成することもできます。 。
  
  8.まとめ
  
  一部の人々は尋ねるかもしれません:CryptGenRandom()のような「/ dev / random」と「true random number generators」があるので、なぜ疑似乱数のような「偽」を提供して使用する必要があるのですか?前述の「/ dev / random」のため、CryptGenRandom()は生成が遅く、より多くのパフォーマンスを消費します。乱数の予測不可能性が低い場合は、パフォーマンスが比較的高いため、疑似乱数アルゴリズムを使用できます。乱数の予測不可能性が高い場合は、真の乱数ジェネレータを使用する必要があります。真の乱数ジェネレータのハードウェア機器はコストの問題を考慮する必要があり、「/ dev / random」とCryptGenRandom()のパフォーマンスは低くなります。
  
  すべてが完璧であり、絶対に良いことはなく、絶対的に悪いこともありません。これが多様な世界の美しさです。

おすすめ

転載: www.cnblogs.com/aquariusunny/p/12729910.html