主な質問1.並行プログラミングエリア
1.1スレッド間の通信
これは、スレッド間で情報を交換するためにどのような機構通信スレッドを指します。プログラミングでは、2つのスレッドは、共有メモリと、メッセージパッシングとの間の通信機構。
共有メモリの同時実行モデルでは、一般的な状態は、書き込むことによって、スレッド間のスレッド間のプログラムを共有-暗黙通信、共有メモリ通信の典型的には、共通の目標状態を共有することによって通信するメモリを読み取ります。
同時実行モデルのメッセージングにおいて、状態間には共通のスレッドが存在しない、明示的に()(Javaのメッセージ待ちである典型的な実施形態では、スレッド間の明示的なメッセージを送信することによって通信する)と通知されなければなりません。
1.2間のスレッド同期
これは、異なるスレッドの発生を制御するためのオペレーティングプログラムとの間の同期機構の相対的な順序を指します。
共有メモリの同時実行モデルでは、明示的な同期が実行されます。プログラマが明示的メソッドまたはスレッド間の相互排除を実行するために必要なコードの一部を指定しなければなりません。
同時実行モデルのメッセージングでは、以降のメッセージを受信する前に送信メッセージは、したがって暗黙の同期が実行されなければなりません。
2.Javaメモリモデル--JMM
上記のJava仮想マシンで実行する必要があるJavaプログラム、Javaのメモリモデル(Javaのメモリモデル、JMM)は、それぞれにそのJavaプログラムを確実にするために、ハードウェアとオペレーティングシステムの様々なへのアクセスの違いをシールド、ラインにおける標準メモリモデルの一種でありますメモリメカニズムへのプラットフォームへのアクセスの種類の下で一貫性のある結果と仕様を確保することができます。
- Java並行処理は、共有メモリモデルを使用しています
2.1現代のコンピュータのメモリモデル
物理コンピュータでの並行性の問題は、状況は多くの類似点、物理マシンの同時治療オプションは、仮想マシンのために存在し、仮想マシンに物理的な問題や機会によって複雑にもかなりの基準値を持っています。
複雑さの一つの重要な供給源は、コンピューティングタスクの大半で、メモリと対話するために、少なくともプロセッサを行うことができ、「コンピューティング」プロセッサに依存することはできません、このような操作データを読み込み、店舗の計算結果として、I / O操作は、(すべてのコンピューティングタスクを完了するために、レジスタによってだけではなく)を除去することは困難です。コンピュータの初期のCPUとメモリの速度はほぼ同じであるが、最近のコンピュータでは、CPUの指令速度ははるかに、数桁のギャップを持つコンピュータプロセッサとメモリデバイスの動作速度以来、その近代的なメモリアクセス速度を超えてプロセッサとの間のバッファとしてのコンピュータシステムの層を追加することが可能とプロセッサ速度キャッシュ限り近い速度を読み書きしなければならなかった(キャッシュ)メモリ:コピー操作は、操作ができるように、キャッシュにデータを使用する必要がありますすぐに、動作時にバックキャッシュメモリからの同期が終了するので、プロセッサの後の読み取りおよび書き込みが遅いメモリを待たずに。
JVMは、Javaスレッド、設計で考慮に入れたときに、それぞれの読み取りと書き込みの変数は、直接メインメモリ、パフォーマンスに大きな影響を操作するので、各スレッドは、メインメモリにメモリ変数を働いて、独自のワーキングメモリを持っている場合コピー、変数のスレッドがメモリ内の主な変数の操作に直接ではない読み取りおよび書き込み操作をワーキングメモリに直接、と。しかし、これはスレッドがその作業メモリ変数を変更し、問題になり、他のスレッドが見えない、不安の問題にスレッドが発生します。JMMは、メモリが他のスレッドに同期化される時期を制御することができ、マルチスレッドプログラムを書いている時点で、開発者を確保するための一連の標準を開発しているため。
メモリの相互運用性
メモリインターワーキングの8種類がありますが、仮想マシンの実装は、いくつかのプラットフォームは、例外を許可上で操作を読み書き、各操作は、ダブル、long型のための変数、ロード、ストアの(ない分で、アトミックであることを確認する必要があります)
-
- ロック(ロック):メインメモリ変数、排他状態にスレッドを識別する変数に作用します
- ロックを解除(アンロック):変数がロックされた状態で放出されることをメインメモリ変数の役割を、変数のリリースは、他のスレッドをロックすることができた後、
- 読み取る(読み出す):次の使用の負荷動作のためのメインメモリ変数、スレッドの作業メモリにメインメモリから送信された変数の値に作用します
- ロード(負荷):ワーキングメモリ変数にメインメモリからの読み出し動作そのワーキングメモリ変数の役割
- use (使用):作用于工作内存中的变量,它把工作内存中的变量传输给执行引擎,每当虚拟机遇到一个需要使用到变量的值,就会使用到这个指令
- assign (赋值):作用于工作内存中的变量,它把一个从执行引擎中接受到的值放入工作内存的变量副本中
- store (存储):作用于主内存中的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的write使用
- write (写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中
JMM对这八种指令的使用,制定了如下规则:
-
- 不允许read和load、store和write操作之一单独出现。即使用了read必须load,使用了store必须write
- 不允许线程丢弃他最近的assign操作,即工作变量的数据改变了之后,必须告知主存
- 不允许一个线程将没有assign的数据从工作内存同步回主内存
- 一个新的变量必须在主内存中诞生,不允许工作内存直接使用一个未被初始化的变量。就是怼变量实施use、store操作之前,必须经过assign和load操作
- 一个变量同一时间只有一个线程能对其进行lock。多次lock后,必须执行相同次数的unlock才能解锁
- 如果对一个变量进行lock操作,会清空所有工作内存中此变量的值,在执行引擎使用这个变量前,必须重新load或assign操作初始化变量的值
- 如果一个变量没有被lock,就不能对其进行unlock操作。也不能unlock一个被其他线程锁住的变量
- 对一个变量进行unlock操作之前,必须把此变量同步回主内存
JMM对这八种操作规则和对volatile的一些特殊规则就能确定哪里操作是线程安全,哪些操作是线程不安全的了。但是这些规则实在复杂,很难在实践中直接分析。所以一般我们也不会通过上述规则进行分析。更多的时候,使用java的happen-before规则来进行分析。