マルチスレッドプログラミングでは、最も重要で最も関係のある問題は、困難なポイントでありコアである同期の問題である必要があります。
JDKの最も早いバージョンの同期と揮発性から、JDK 1.5で提供されるJava.util.concurrent.Locksパッケージのロックインターフェイスまで(実装にはReadLock、Writelock、およびReentrantLockが含まれます)、マルチスレッドの実装も徐々に成熟しています。
同期を制御するために使用されるメカニズムは何ですか?最初の反応はロックすることです。これは、オペレーティングシステムとデータベースを学習するときにさらされるはずです。 Javaマルチスレッドプログラムでは、複数のプログラムが同じリソースを競う場合、リソースの腐食を防ぐために、リソースにアクセスする最初のスレッドにオブジェクトロックが割り当てられ、その後の世代はこのオブジェクトロックのリリースを待つ必要があります。
はい、Javaスレッドの同期について最も懸念されることは、共有リソースの使用です。
まず、どのスレッドが利用できるかについての共有リソースをいくつか理解しましょう。
JVMから、スレッドで共有されるデータを調整する必要があります。
1.ヒープに保存されたインスタンス変数。 2。メソッド領域に保存されたクラス変数。
Java仮想マシンがクラスをロードすると、各オブジェクトまたはクラスがモニターに関連付けられて、オブジェクトのインスタンス変数またはクラス変数を保護します。もちろん、オブジェクトにインスタンス変数がない場合、またはクラスに変数がない場合、モニターは何も監視しません。
上記のモニターのミューテックスを実現するために、仮想マシンは、各オブジェクトまたはクラスのロック(目に見えないロックとも呼ばれます)を関連付けます。クラスがロードされると、JVMが各クラスのjava.lang.classのインスタンスを作成するため、クラスロックもオブジェクトロックを介して実装されていることをここで説明させてください。したがって、ロックがオブジェクトに反している場合、このクラスのクラスオブジェクトがロックされます。
さらに、スレッドは複数のリリースに対応するオブジェクトを複数回ロックできます。これは、各オブジェクトロックに対してJVMが提供するロック計算機です。最後のロックが追加され、対応するマイナス1が追加され、電卓値が0の場合、リリースされます。このオブジェクトロックは、JVM内のモニターによって使用され、JVMによって自動的に生成されます。すべてのプログラマーは自分で追加する必要はありません。
Javaの同期原理を導入した後、トピックに到達し、最初に同期の使用について話します。その他の同期は、次の章で紹介されます。
最初に例を実行してみましょう。
パッケージスレッド_test; / ***スレッドクラスの実装を拡張するマルチスレッドプログラムをテスト* public testthread(int threadnum){this.threadnum = threadnum; } @Override public synchronized void run(){for(int i = 0; i <1000; i ++){system.out.println( "no。" + threadnum + ":" + i); }} public static void main(string [] args)throws exception {for(int i = 0; i <10; i ++){new testthread(i).start(); thread.sleep(1); }}}
実行結果:
No.0:887 No.0:888 No.0:889 No.0:890 No.0:891 No.0:892 No.0:893 No.0:894 No.7:122 No.7:123 No.7:124
上記は単なるクリップであり、問題を説明しています。
注意している場合は、No.0:894の後にNo.7:122が続くことがわかります。つまり、0から999に開始されません。
同期化された同期メソッドまたは同期ブロックを実装できると言われていますが、なぜここで機能しないのですか?
まず、同期メカニズムを分析しましょう。同期は、ロックを通じて達成されます。上記の例では、どのオブジェクトがロックされていますか、またはどのクラスがロックされていますか?内部には2つの変数があります。1つはi、もう1つはthreadnumです。私はこの方法の内部であり、Threadnumはプライベートです。
同期したランニングメカニズムについて学びましょう:
Javaプログラムでは、同期されたブロックまたは同期メソッドが使用されると、この領域は監視にマークされています。 JVMがプログラムを処理するとき、プログラムが監視エリアに入ると、オブジェクトまたはクラスを自動的にロックします。
上記の例では、同期されたキーワードが使用された後にロックされたものは何ですか?
同期した場合、メソッド自体をオブジェクトロックとして呼び出すインスタンスオブジェクトをロックします。この例では、10個のスレッドに独自のTestThreadクラスオブジェクトがあるため、取得したオブジェクトロックは独自のオブジェクトロックであり、他のスレッドとは何の関係もありません。
メソッドロックを実装するには、共有オブジェクトをロックする必要があります。
上記の例を変更してから、次をご覧ください。
パッケージスレッド_test; / ***スレッドクラスの実装を拡張するマルチスレッドプログラムをテスト*プライベートストリングフラグ。 // public testthread(int threadnum、string flag){this.threadnum = threadnum; this.flag = flag; } @Override public void run(){synchronized(flag){for(int i = 0; i <1000; i ++){system.out.println( "no。" + threadnum + ":" + i); }}} public static void main(string [] args)throws exception {string flag = new String( "flag"); for(int i = 0; i <10; i ++){new testThread(i、flag).start(); thread.sleep(1); }}}
これには共有フラグも追加されます。次に、フラグフラグは同期ブロックを介して同期されます。これは、共有オブジェクトをロックする条件を満たします。
はい、実行中の結果が整然となっています。
同期ブロックを介して、オブジェクトロックの取得を指定して、同期を実現します。それでは、同期された方法で実装できる他のメソッドはありますか?
同期の原則に従って:共有オブジェクトロックまたはクラスロックを取得できる場合、同期を実現できます。それで、クラスロックを共有することでそれを達成できますか?
はい、静的同期方法を使用できます。静的メソッドの特性によれば、クラスオブジェクト自体を呼び出すことのみを可能にし、クラスオブジェクトをインスタンス化することによって呼び出されません。次に、この静的メソッドのロックを取得すると、クラスロックが取得され、このクラスロックはすべてTestThreadクラスロックであり、共有クラスロックを取得する目的が達成されます。
実装コードは次のとおりです。
パッケージスレッド_test; / ** *スレッドクラスの実装を拡張するマルチスレッドプログラムをテスト * public testthread(int threadnum){this.threadnum = threadnum; } public static同期void statictest(int threadnum){for(int i = 0; i <1000; i ++){system.out.println( "no。" + threadnum + ":" + i); }} public static void main(string [] args)throws exception {for(int i = 0; i <10; i ++){new testthread(i).start(); thread.sleep(1); }} @Override public void run(){statictest(threadnum); }}実行結果は省略されており、2番目の例と同じです。
上記のコンテンツは、主に同期ブロックと同期方法の2つの問題を説明しています。
1。同期ブロック:取得したオブジェクトロックは、同期(フラグ)のフラグオブジェクトロックです。
2。同期方法:メソッドが属するクラスオブジェクトとクラスオブジェクトはロックします。
複数のスレッドが共有されるため、静的同期方法は間違いなく同期されます。
静的同期方法の代わりに、シングルトンモードでのみ同期されます。