web-dev-qa-db-ja.com

Javaのネイティブスレッドとjvmを理解する

Jvm自体がJava実行可能ファイルのバイトコードをネイティブマシンコードに変換するアプリケーションであることを理解していますが、ネイティブスレッドを使用する場合、答えられないような質問がいくつかあります。

  • すべてのスレッドは、特定の実行を処理するためにjvmの独自のインスタンスを作成しますか?
  • そうでない場合、jvmは次に処理するスレッドをスケジュールする何らかの方法を備えている必要がありますか?そうでない場合、これはJavaのマルチスレッドの性質を無意味にします)一度に走った?
33
Traker

すべてのスレッドは、特定の実行を処理するために、JVMの独自のインスタンスを作成しますか?

いいえ。それらは同じJVMで実行されるため、(たとえば)オブジェクトとクラス属性を共有できます。


そうでない場合、JVMは次に処理するスレッドをスケジュールする方法を持っている必要がありますか

Javaには2種類のスレッド実装があります。ネイティブスレッドは、ホストOSによって実装されるスレッド抽象化にマップされます。 OSは、ネイティブスレッドのスケジューリングとタイムスライシングを処理します。

2番目の種類のスレッドは「グリーンスレッド」です。これらはJVM自体によって実装および管理され、JVMはスレッドスケジューリングを実装します。 Javaグリーンスレッドの実装は、Java 1.2以降、Sun/Oracle JVMではサポートされていません。( グリーンスレッドと非グリーンスレッド を参照) )


もしそうなら、これは一度に1つのスレッドしか実行できないため、Javaのマルチスレッドの性質を役に立たないでしょうか?

私たちは今グリーンスレッドについて話している、そしてこれはJavaの観点から)歴史的に興味深い(のみ)。

  • グリーンスレッドには、非I/Oの場合にスケジューリングとコンテキスト切り替えが高速になるという利点があります。 (Linux2.2ではJava)で行われた測定に基づく; http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.9238

  • 純粋なグリーンスレッドでは、N個のプログラミング言語スレッドが単一のネイティブスレッドにマップされます。ご指摘のとおり、このモデルでは真の並列実行は得られません。

  • ハイブリッドスレッドの実装では、N個のプログラミング言語スレッドがM個のネイティブスレッド(N> M)にマップされます。このモデルでは、インプロセススレッドスケジューラがグリーンスレッドからネイティブスレッドへのスケジューリングを担当し、真の並列実行を取得します(M> 1の場合)。 https://stackoverflow.com/a/16965741/139985 を参照してください。

しかし、純粋な緑のスレッドを使用しても、並行性は得られます。制御は、I/O操作でスレッドがブロックする別のスレッドに切り替えられ、ロックの取得などが行われます。さらに、JVMのランタイムは定期的なスレッドプリエンプションを実装できるため、CPUを集中的に使用するスレッドが(単一の)コアを独占して他のスレッドを除外することはありません。

30
Stephen C

すべてのスレッドは、特定の実行を処理するためにjvmの独自のインスタンスを作成しますか?

いいえ、JVMで実行されているアプリケーションには、JVMのそのインスタンス内にすべて存在する多くのスレッドを含めることができます。

そうでない場合、jvmは次に処理するスレッドをスケジュールする何らかの方法を持っている必要がありますか...

はい、JVMにはスレッドスケジューラがあります。スレッドスケジューリングにはさまざまなアルゴリズムがあり、どれを使用するかはJVMベンダーに依存します。 ( スケジューリング 一般的には興味深いトピックです。)

...もしそうなら、これはJavaのマルチスレッドの性質を、一度に1つのスレッドしか実行できないので役に立たないものにしませんか?

私はあなたの質問のこの部分を理解しているかどうかわかりません。これは一種のスレッド化のポイントです。通常、CPUよりも多くのスレッドがあり、一度に複数のものを実行する必要があります。スレッド化を使用すると、別のスレッドがI/Oを待機している間、または他の理由でビジーでないスレッドの処理でビジー状態になるようにすることで、CPUを最大限に活用できます。

7
Bill the Lizard

Javaスレッドはカーネルスレッドに1対1でマップできますが、そうではないはずです。mJavaここで、mはnよりはるかに大きく、nはプロセッサの数よりも大きい必要があります。JVM自体がn個のカーネルスレッドを開始し、それぞれがJavaスレッドとしばらく実行してから、他のJava=スレッドに切り替えます。オペレーティングシステムはカーネルスレッドを選択してCPUに割り当てます。そのため、いくつかのレベルでスレッドスケジューリングが行われる可能性があります。数千のいわゆる「カーネル」が数十のスレッドによって実行されるGOプログラミング言語を見てみましょう。

6
muh

JavaスレッドはネイティブOSスレッドにマップされます。それらはJVM自体とはほとんど関係がありません。

1
Bozhidar Batsov