web-dev-qa-db-ja.com

JavaスレッドとOSスレッド

Javaスレッド/ OSスレッドとインタープリター言語を台無しにしたようです。

始める前に、グリーンスレッドはJavaスレッドであり、スレッドはJVMによって処理され、Javaプロセス全体が単一のOSスレッドとしてのみ実行されることを理解しています。そのため、マルチプロセッサシステムでは役に立ちません。

今私の質問はです。 2つのスレッドAとBがあります。それぞれに10万行の独立したコードがあります。これらのスレッドは、マルチプロセッサシステムのJavaプログラムで実行します。各スレッドには、異なるCPUで実行できるRUNへのネイティブOSスレッドが与えられますが、Javaが解釈されるため、これらのスレッドは、バイトコードをマシン命令に変換するためにJVMと何度も対話する必要がありますか?私は正しいですか?はいの場合、小さなプログラムよりもJavaスレッドは大きな利点にはなりませんか?

ホットスポットが両方の実行パスをコンパイルすると、どちらもネイティブスレッドと同じくらい良いものになりますか?私は正しいですか?

[編集]:別の質問は、コードがJITコンパイルされていない単一のJavaスレッドがあると仮定して、そのスレッドを作成してstart()することです。 OSスレッドとJVMはどのように相互作用してそのバイトコードを実行しますか?

ありがとう

33
Geek

各スレッドには、異なるCPUで実行できるRUNへのネイティブOSスレッドが与えられますが、Javaが解釈されるため、これらのスレッドは、バイトコードを変換するためにJVMと何度も対話する必要があります。機械の指示?私は正しいですか?

あなたは2つの異なるものを混ぜています。 VMによって実行されるJITとVMによって提供されるスレッドサポート。内部の奥深くで、実行するすべてが何らかのネイティブコードに変換されます。スレッドを使用するバイトコード命令は、スレッドにアクセスするJITされたコード。

はいの場合、小さなプログラムよりもJavaスレッドは大きな利点にはなりませんか?

ここで小さく定義します。短期間のプロセスの場合、そうです。順次実行は十分に高速であるため、スレッド化による大きな違いはありません。これも、解決する問題によって異なることに注意してください。 UIツールキットの場合、アプリケーションがどんなに小さくても、UIの応答性を維持するには、何らかのスレッド化/非同期実行が必要です。

スレッド化は、canを並行して実行できるものがある場合にも意味があります。典型的な例は、スレッドで重いIOを実行し、別のスレッドで計算を実行することです。メインスレッドがIOの実行をブロックされているという理由だけで、処理をブロックしたくない場合があります。

ホットスポットが両方の実行パスをコンパイルすると、どちらもネイティブスレッドと同じくらい良いものになりますか?私は正しいですか?

私の最初のポイントを参照してください。

スレッド化は、特に「スレッドを使用してこのコードを高速化する」という一般的な誤解に関しては、特効薬ではありません。少しの読書と経験が最善の策です。 この素晴らしい本 のコピーを入手することをお勧めできますか? :-)

@Sanjay:実際、質問を再構成できるようになりました。コードがJITされていないスレッドがある場合、OSスレッドはどのようにそれを実行しますか?

繰り返しになりますが、スレッド化はJITとはまったく異なる概念です。プログラムの実行を簡単な言葉で見てみましょう。

Java pkg.MyClass-> VM実行するメソッドを検索->メソッドのバイトコードの実行を1行ずつ開始->各バイトコード命令をネイティブの対応する命令に変換->実行された命令OSによる->マシンによって実行される命令

JITが開始されたとき:

Java pkg.MyClass-> VM実行するメソッドを検索しますJITされています->関連するメソッドを検索しますネイティブそのメソッドのコード-> OSによって実行される命令->マシンによって実行される命令

ご覧のとおり、ルートに関係なく、VM命令は、ある時点でネイティブの対応する命令にマップする必要があります。そのネイティブコードを保存して、さらに再利用するか、別のものがあれば捨てられます(最適化、覚えていますか?)。

したがって、あなたの質問に答えるために、スレッデッドコードを書くときはいつでも、それはisネイティブコードに変換され、by OSを実行します。その翻訳がその場で行われるのか、その時点で調べられるのかは、まったく別の問題です。

25

そして、Javaプロセス全体は単一のOSスレッドとしてのみ実行されます

本当じゃない。したがって、指定されていない場合、Javaスレッドは実際にはネイティブOSスレッドであり、マルチスレッドJavaアプリケーションは実際にマルチコアプロセッサまたはマルチを使用します。 -プロセッサプラットフォーム。

一般的な推奨事項は、スレッドの数がコアの数に比例するスレッドプールを使用することです(係数1〜1.5)。これは、JVMが単一のOSスレッド/プロセスに制限されていないというもう1つのヒントです。


ウィキペディアから:

Java 1.1では、少なくともSolarisではグリーンスレッドがJVMで使用される唯一のスレッドモデルでした[4]。グリーンスレッドにはネイティブスレッドと比較していくつかの制限があるため、後続= Javaバージョンはネイティブスレッドを優先してそれらを削除しました

さて、2010年にJava 7が開発中で、Java 8が計画されています-私たちはまだ歴史的な「グリーンスレッド」に本当に興味がありますか?

10
Andreas_D
  1. 一部のJava実装では、説明したようにグリーンスレッドが作成される場合があります(単一のネイティブスレッドでJVMによって行われるスケジューリング)が、PCでのJavaの通常の実装では、複数のコアが使用されます。
  2. JVM自体は、実行する作業(ガベージコレクション、クラスのロード、バイトコード検証、JITコンパイラ)にすでに異なるスレッドを使用している可能性があります。
  3. OSはJVMと呼ばれるプログラムを実行します。 JVMはJavaバイトコードを実行します。すべてのJavaスレッドにネイティブスレッドが関連付けられている場合(これは理にかなっており、PC実装の場合のようです)、そのスレッドのJVMコードは、シングルスレッドのようにJavaコード(JITまたはインタープリター)を実行します。 -プログラム。マルチスレッドによる違いはありません。
3
Mnementh

バイトコードのスレッド化と実行は別の問題です。グリーンスレッドは、スレッドのネイティブサポートがないプラットフォーム上のJVMによって使用されます。 (私見では、どのプラットフォームがスレッドをサポートしていないのかわかりません)。

バイトコードはリアルタイムで解釈され、JVMによってネイティブプラットフォームで実行されます。 JVMは、最も人気のあるコードフラグメントを決定し、これらのフラグメントのいわゆるジャストインタイムコンパイルを実行するため、何度もコンパイルする必要はありません。これはスレッド化とは無関係です。たとえば、ループ内で同じコードフラグメントを実行するスレッドが1つある場合、このフラグメントはジャストインタイムコンパイラによってキャッシュされます。

結論:パフォーマンスとスレッドについて心配する必要はありません。 Javaは、コーディングしているすべてのものを実行するのに十分な強度があります。

2
AlexR