1。プロセスとスレッドの概念
(1)従来のオペレーティングシステムでは、プログラムは独立して実行できず、リソース割り当てと独立操作の基本単位はすべてプロセスであるためです。
OSのないシステムでは、プログラムの実行方法は順次実行されます。つまり、別のプログラムを実行する前に、1つのプログラムを実行する必要があります。マルチプログラム環境では、複数のプログラムを同時に実行できます。プログラムの実行方法には大きな違いがあります。まさに、オペレーティングシステムでプロセスの概念の導入につながるプログラムの同時実行のこの特徴です。
1960年代に人々がプロセスの概念を提案したため、Processは常にリソースを持ち、独立して実行できる基本ユニットとしてOSで使用されてきました。 1980年代半ばまで、人々は、プロセスよりも小さいスレッドを独立して実行できる基本ユニットを提案し、システム内のプログラムの同時実行の程度を増やすために使用しようとするため、システムのスループットがさらに増加しました。特に1990年代に入った後、マルチプロセッサシステムは急速に発展しました。スレッドは、プロセスよりもプログラムの並列実行を改善し、マルチプロセッサの利点を完全に発揮できます。したがって、OSのパフォーマンスを改善するために、近年発売されたマルチプロセッサOSにスレッドが導入されています。
- 上記は「コンピューターオペレーティングシステム - Tang Xiaodan and Othersにより編集された「コンピューターオペレーティングシステム」から抜粋
(2)次の図は、Zhihuユーザーからの説明です。
上記の一般的な理解を通じて、基本的にスレッドとプロセスが何をするかを知っています。以下のプロセスとスレッドの概念を要約しましょう。
(3)プロセスは、特定のデータセットに関するコンピューター内のプログラムの実行アクティビティであり、システムのリソース割り当てとスケジューリングの基本単位であり、オペレーティングシステム構造の基礎です。初期のプロセス指向のコンピューター構造では、プロセスはプログラムの基本的な実行エンティティでした。現代のスレッド指向のコンピューター構造では、プロセスはスレッドの容器でした。プログラムは、指示、データ、およびその組織形式の説明であり、プロセスはプログラムのエンティティです。
(4)ライトウェイトプロセス(LWP)と呼ばれるスレッドは、プログラム実行フローの最小単位です。スレッドは、プログラム内の単一のシーケンシャル制御プロセスです。プロセス内の比較的独立したスケジュール可能な実行ユニットは、システム内の独立したスケジューリングとディスパッチCPUの基本ユニットであり、これはランニングプログラムのスケジューリングユニットを指します。単一のプログラムで複数のスレッドを同時に実行して、マルチスレッドと呼ばれるさまざまな作業を完了します。
(5)プロセスとスレッドの関係:
2。Javaはマルチスレッド法を実装します
(1)スレッドを継承し、run()メソッドを書き直します
public class mythread extends thread {@override public void run(){while(true){system.out.println(this.currentthread()。getName()); }} public static void main(string [] args){mythread thread = new mythread(); thread.start(); //スレッドを開始する正しい方法}}出力結果:
Thread-0thread-0thread-0 ...
さらに、start()メソッドはrun()メソッドの代わりにstart()メソッドであることを理解する必要があります。 run()メソッドを使用する場合、実行するのは通常の方法です。
(2)実行可能なインターフェイスを実装します
パブリッククラスmyRunnableはrunnable {@override public void run(){system.out.println( "123"); } public static void main(string [] args){myrunnable myrunnable = new myRunnable();スレッドスレッド= newスレッド(myrunnable、 "t1"); thread.start(); }}3。スレッドの安全
スレッドの安全性の概念:複数のスレッドが特定のクラス(オブジェクトまたはメソッド)にアクセスすると、クラスは常に正しい動作を表示でき、このクラス(オブジェクトまたはメソッド)はスレッドセーフです。
スレッドの安全性は、マルチスレッドにアクセスするときに、ロックメカニズムが採用されます。スレッドがクラスの特定のデータにアクセスすると、保護されます。他のスレッドは、スレッドが読み取りが終了するまでアクセスできず、他のスレッドはそれを使用できません。データの矛盾やデータ汚染はありません。スレッドは安全ではありません。つまり、データアクセス保護は提供されません。複数のスレッドが次々とデータを変更し、結果のデータが汚れている可能性があります。ここでの一般的なロックメカニズムは次のとおりです。同期
4。同期修飾子
(1)同期:任意のオブジェクトとメソッドにロックを追加でき、ロックされたコードは「ミューテックス領域」または「クリティカルエリア」と呼ばれます。
(2)**使用しないでください**同期インスタンス(コードA):
パブリッククラスのmythreadはスレッド{private int count = 5; @override public void run(){count - ; system.out.println(this.currentthread()。getname() + "count:" + count);} public static void main(string [] args){mythread mythread = new mythread(); new swrews( "; new swrep); thread(mythread、 "thread2"); thread 3 = new shood(mythread、 "thread3"); thread4 = new thread(mythread、 "thread4"); thread5 = new swerch(mythread、 "thread5"); thread1.start(); thread2.start(); thread2.start(); thread3.start(); swrept(); swert(); sthread(); sthread(); sthread(); sthread();出力の結果の1つは次のとおりです。
Thread3カウント:2ThRead4カウント:1THREAD1カウント:2THREAD2カウント:3THREAD5カウント:0
複数のスレッドがrun()メソッドを同時に動作させ、カウントを変更し、エラーを引き起こすため、上記の結果が正しくないことがわかります。
(3)**使用**同期インスタンス(コードB):
パブリッククラスMythreadはスレッドを拡張します{private int count = 5; @Override public synchronized void run(){count--; system.out.println(this.currentthread()。getname() + "count:" + count); } public static void main(string [] args){mythread mythread = new mythread();スレッドスレッド1 =新しいスレッド(mythread、 "thread1");スレッドスレッド2 =新しいスレッド(mythread、 "thread2");スレッドスレッド3 =新しいスレッド(mythread、 "thread3");スレッドスレッド4 =新しいスレッド(mythread、 "thread4");スレッドスレッド5 =新しいスレッド(mythread、 "thread5"); thread1.start(); thread2.start(); thread3.start(); thread4.start(); thread5.Start(); }}出力結果:
Thread1カウント:4Thread2カウント:3THREAD3カウント:2THREAD5カウント:1THREAD4カウント:0
コードAとコードBの違いは、同期された変更がrun()メソッドに追加されることであることがわかります。
説明は次のとおりです。
複数のスレッドがMythRead Runメソッドにアクセスすると、同期変更された変更が使用される場合、マルチスレッドはキューで処理されます(ここのキューはCPU割り当ての順序に従って決定されます)。スレッドが同期変更方法でコードを実行したい場合、最初にロックを取得しようとします。ロックを取得した場合は、同期コード本体の内容を実行します。ロックを取得できない場合、スレッドはロックを取得するまでロックを取得しようとし続けます。さらに、複数のスレッドが同時にロックを競うため、ロック競争が発生することを意味します。
5。オブジェクトにはロックがあります!複数のスレッドと複数のロック!
1つのオブジェクトには1つのロックがあり、複数のスレッドには複数のロックがあります!まず、以下のサンプルコード(コードC)を見てみましょう。
Public Class MultiThread {private int num = 200; public synchronized void printnum(string threadname、string tag){if(tag.equals( "a")){num = num -100; system.out.println(threadname + "タグA、num over!"); } else {num = num -200; System.out.println(threadname + "tag" + tag + "、num =" + num); } public static void main(string [] args)throws arturnedexception {final multithread multithread1 = new MultithRead();最終的なMultithRead MultithRead2 = new MultithRead(); new Sthread(new runnable(){public void run(){multithread1.printnum( "thread1"、 "a");}})。start(); thread.sleep(5000); system.out.println( "Sthread1が実行されていることを確認するために5秒待ってください!");新しいスレッド(new runnable(){public void run(){multithread2.printnum( "thread2"、 "b");}})。start(); }}出力結果:
thread1タグA、num over!thread1タグA、num = 100wait 5秒を設定して、thread1が実行されていることを確認してください! Thread2タグB、num over!thread2タグB、num = 0を設定します
MultiThRead1とMultiThRead2の2つのオブジェクトがあることがわかります。複数のオブジェクトが同じロックを使用する場合、上記の実行の結果は次のようにする必要があります:thread2タグB、num = -100。したがって、各オブジェクトにはそのオブジェクトのロックがあります。
同期されたキーワードによって得られたロックは、コードまたはメソッドをロックとして扱うのではなく、オブジェクトロックです。したがって、上記の例コードCでは、スレッドが最初に同期されたキーワードメソッドを実行すると、スレッドはメソッドが属するオブジェクトのロックを保持します。スレッドは、2つの異なるオブジェクトの2つの異なるロックを取得し、互いに補完します。
したがって、通常のシナリオでは、すべてのオブジェクトが変数カウントで動作する状況がある必要があります。静的を追加するのは非常に簡単です。このクラスのすべてのオブジェクトには、どのようなオブジェクトがインスタンス化されていても、コールがメソッドであり、コードは次のとおりです(コードD)と同じ参照があることがわかっています。
Public Class MultiThread {private static int num = 200; public static同期void printnum(string threadname、string tag){if(tag.equals( "a")){num = num -100; system.out.println(threadname + "タグA、num over!"); } else {num = num -200; System.out.println(threadname + "タグB、num over!"); } system.out.println(threadname + "tag" + tag + "、num =" + num); } public static void main(string [] args)throws arturnedexception {final multithread multithread1 = new MultithRead();最終的なMultithRead MultithRead2 = new MultithRead(); new Sthread(new runnable(){public void run(){multithread1.printnum( "thread1"、 "a");}})。start(); thread.sleep(5000); system.out.println( "Sthread1が実行されていることを確認するために5秒待ってください!");新しいスレッド(new runnable(){public void run(){multithread2.printnum( "thread2"、 "b");}})。start(); }}出力結果:
thread1タグA、num over!thread1タグA、num = 100wait 5秒を設定して、thread1が実行されていることを確認してください! thread2タグB、num over!thread2タグB、num = -100を設定します
変数とメソッドに静的な変更を追加すると、必要なシナリオを実現できることがわかります。また、非静的な静的修正方法または変数については、ロックされたオブジェクトを示しています。
6。同期および非同期オブジェクトロック
(1)同期
同期の概念は共有されています。 「共有」という言葉は共有リソースではなく、同期する必要はないことを知る必要があります。つまり、ロックする必要はありません。
同期の目的は、スレッドの安全性を確保することです。実際、スレッドの安全性については、2つの最も基本的な特性を満たす必要があります。原子性と視認性。
(2)非同期:非同期
非同期性の概念は独立性であり、互いに制約がなく、両者の間に関係はありません。
(3)サンプルコード:
public class myobject {public void method(){system.out.println(thread.currentthread()。getname()); } public static void main(string [] args){final myobject myobject = new Myobject();スレッドt1 = newスレッド(new runnable(){public void run(){myobject.method();}}、 "t1");スレッドT2 = newスレッド(new runnable(){public void run(){myobject.method();}}、 "t2"); t1.start(); t2.start(); }}上記のコードでは、method()は非同期方法です。
要約します
上記は、Javaマルチスレッドでスレッド、プロセス、同期の概念に対する最初の解決策に関するこの記事の内容全体です。私はそれが誰にでも役立つことを願っています。欠点がある場合は、メッセージを残して指摘してください。編集者は、すべての人に時間内に返信します。