Javaマルチスレッド使用の最も包括的な分析。 Javaのマルチスレッドメカニズムに関する詳細な研究を行っていない場合、この記事は、Javaマルチスレッドの原則と使用方法をより徹底的に理解するのに役立ちます。
1.スレッドを作成します
Javaにスレッドを作成するには、スレッドクラスを使用して実行可能なインターフェイスを使用する方法は2つあります。実行可能なインターフェイスを使用する場合、スレッドインスタンスを作成する必要があります。したがって、スレッドクラスまたは実行可能なインターフェイスを介してスレッドを確立するかどうかにかかわらず、スレッドクラスまたはそのサブクラスのインスタンスを確立する必要があります。スレッドコンストラクター:
方法1:スレッドクラスを継承し、実行方法を上書きする
public class threaddemo1 {public static void main(string [] args){demo d = new demo(); D.Start(); for(int i = 0; i <60; i ++){system.out.println(thread.currentthread()。getname()+i); }}} class demo extends thread {public void run(){for(int i = 0; i <60; i ++){system.out.println(thread.currentthread()。getName()+i); }}}方法2:
public class threaddemo2 {public static void main(string [] args){demo2 d = new demo2();スレッドT =新しいスレッド(d); t.start(); for(int x = 0; x <60; x ++){system.out.println(thread.currentthread()。getname()+x); }}} class demo2はrunnable {public void run(){for(int x = 0; x <60; x ++){system.out.println(thread.currentthread()。getName()+x); }}}2。スレッドのライフサイクル
人々が出生、老年、病気、死を持っているように、糸も4つの異なる状態を通過する必要があります。 4つの状態はすべて、スレッドクラスのメソッドによって制御できます。以下は、スレッドクラスのこれらの4つの状態に関連する方法です。
//スレッドを起動します
publicVoid start();
publicVoid run();
//スレッドを一時停止して目覚めます
publicVoid resume(); //使用することをお勧めしません
publicVoid suspend(); //使用することをお勧めしません
publicStaticVoid睡眠(長いミリ);
publicStaticVoid Sleep(Long Millis、int nanos);
//スレッドを終了します
publicVoid stop(); //使用することをお勧めしません
publicVoid割り込み();
//スレッド状態を取得します
publicboolean isalive();
publicboolean is utterrupded();
publicStaticBooleanが中断されました();
//メソッドに参加します
publicVoid join()throws arturtedexception;
スレッドが確立された後、すぐに実行方法でコードを実行するのではなく、待機状態にあります。スレッドが待機状態にある場合、スレッドクラスメソッドを使用して、スレッドの優先度(setpriority)、スレッド名(setName)、スレッドタイプ(setDaemon)など、スレッドのさまざまなプロパティを設定できます。
STARTメソッドを呼び出した後、スレッドは実行方法でコードの実行を開始します。スレッドは実行中の状態に入ります。スレッドクラスの等方的な方法を使用して、スレッドが実行されている状態であるかどうかを判断できます。スレッドが実行中の状態にある場合、ISALIVEは真実であります。 ISALIVEがFALSEを返すと、スレッドは待機状態または停止状態にある可能性があります。次のコードは、スレッドの作成、実行、停止の3つの状態間の切り替えを示し、対応するisalive戻り値を出力します。
スレッドが実行方法の実行を開始すると、実行方法が実行されるまでスレッドは終了しません。ただし、スレッドの実行中、スレッドは2つの方法で一時的に停止できます。これらの2つの方法は、中断と睡眠です。スレッドを吊り下げた後、スレッドを履歴書方法で目覚めることができます。睡眠を使用して睡眠を使用した後、スレッドは設定された時間の後にのみ準備ができた状態に配置できます(スレッドが睡眠後、スレッドはすぐに実行されない場合がありますが、準備が整った状態に入り、システムがスケジュールされるのを待ちます)。
睡眠方法を使用するときに注意すべき2つのことがあります。
1.睡眠方法には2つの過負荷フォームがあります。過負荷フォームの1つはミリ秒に設定できますが、ナノ秒(1,000,000ナノ秒が1ミリ秒等)。ただし、ほとんどのオペレーティングシステムプラットフォーム上のJava仮想マシンは、ナノ秒に対して正確にすることはできないため、ナノ秒が睡眠に設定されている場合、Java仮想マシンはこの値に最も近いミリ秒を取ります。
2。スリープ方法を使用する場合、スローを使用するか、{…} catch {…}を試してみる必要があります。実行方法はスローを使用できないため、try {…} catch {…}のみを使用できます。スレッドが眠っているとき、睡眠は、割り込み方法を使用してスレッドを中断するときに中断されたエクセプトの例外を投げます。睡眠方法は次のように定義されています。
publicStaticVoid睡眠(長いミリ)は、中断のエクセプトを投げます
publicStaticVoid Sleep(Long Millis、int nanos)は、中断されたexceptionを投げます
スレッドを終了するには3つの方法があります。
1.出口フラグを使用して、スレッドを通常の出口にすること、つまり、実行方法が完了するとスレッドが終了します。
2。停止方法を使用してスレッドを強制的に終了します(停止は一時停止と履歴書と同じであり、予測不可能な結果もある可能性があるため、この方法は推奨されません)。
3.割り込み方法を使用して、スレッドを中断します。
1.出口フラグを使用して、スレッドを終了します
実行方法が実行されると、スレッドは終了します。しかし、実行方法が終了しない場合があります。たとえば、スレッドを使用して、サーバープログラムのクライアント要求、またはループ処理が必要なその他のタスクをリッスンします。この場合、これらのタスクは通常、whileループなどのループに配置されます。ループを永久に実行したい場合は、while(true){…}を使用して処理できます。ただし、特定の条件下でwhileループを出るようにしたい場合は、最も直接的な方法は、ブール型フラグを設定し、このフラグをtrueまたはfalsに設定することでループが終了するかどうかを制御することです。 Exitフラグを使用してスレッドを終了する例は次のとおりです。
結合方法の関数は、非同期実行スレッドを同期実行に変えることです。つまり、スレッドインスタンスの開始方法が呼び出されると、メソッドはすぐに戻ります。開始方法が呼び出された後にこのスレッドによって計算された値を使用する必要がある場合、結合メソッドを使用する必要があります。 Joinメソッドを使用しない場合、Startメソッドの背後にあるステートメントが実行されると、スレッドが実行されることを保証することはできません。結合メソッドを使用した後、プログラムはスレッドが終了するまで実行されません。次のコードは、結合の使用を示しています。
3。マルチスレッドの安全性の問題
問題の原因:複数のステートメントが同じスレッドで動作してデータを共有している場合、1つのスレッドは複数のステートメントの一部のみを実行しますが、まだ実行が完了しておらず、別のスレッドが実行に参加し、データの共有にエラーが発生します。
解決策:データを複数の操作と共有する複数のステートメントの場合、1つのスレッドのみを実行できます。実行プロセス中、他のスレッドは実行されません。
コードブロックの同期:
public class threaddemo3 {public static void main(string [] args){チケットt = newチケット();スレッドT1 =新しいスレッド(t、 "ウィンドウ1");スレッドT2 =新しいスレッド(t、 "ウィンドウ2");スレッドT3 =新しいスレッド(t、 "ウィンドウ3");スレッドT4 =新しいスレッド(t、 "ウィンドウ4"); t1.start(); t2.start(); t3.Start(); t4.start(); }} classチケット実装runnable {private intチケット= 400; public void run(){while(true){synchronized(new object()){try {thread.sleep(1); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } if(ticket <= 0)break; system.out.println(thread.currentthread()。getname()+"--- sell"+ticket-); }}}}同期関数
public class threaddemo3 {public static void main(string [] args){チケットt = newチケット();スレッドT1 =新しいスレッド(t、 "ウィンドウ1");スレッドT2 =新しいスレッド(t、 "ウィンドウ2");スレッドT3 =新しいスレッド(t、 "ウィンドウ3");スレッドT4 =新しいスレッド(t、 "ウィンドウ4"); t1.start(); t2.start(); t3.Start(); t4.start(); }} classチケット実装runnable {private intチケット= 4000; public synchronized void saleticket(){if(ticke> 0)system.out.println(thread.currentthread()。 } public void run(){while(true){saleticket(); }}}同期関数ロックは、この静的同期関数ロックがクラスです
スレッド間の通信
public class threaddemo3 {public static void main(string [] args){class person {public string name;プライベートストリングジェンダー; public void set(string name、string gender){this.name = name; this.gender = gender; } public void get(){system.out.println(this.name+"...."+this.gender); }}最終人p = new person();新しいスレッド(new runnable(){public void run(){int x = 0; while(true){if(x == 0){p.set( "zhang san"、 "male");} else {p.set( "lili"、 "nv");} x =(x+1)%2;}}})。 newスレッド(new runnable(){public void run(){while(true){p.get();}}})。start(); }}/ *Zhang San ....男性Zhang San ....男性リリ.... nvlili ....男性Zhang San .... nvlili ....男性 */上記のコードを変更します
public class threaddemo3 {public static void main(string [] args){class person {public string name;プライベートストリングジェンダー; public void set(string name、string gender){this.name = name; this.gender = gender; } public void get(){system.out.println(this.name+"...."+this.gender); }}最終人p = new person();新しいスレッド(new runnable(){public void run(){int x = 0; while(true){synchronized(p){if(x == 0){p.set( "zhang san"、 "male");}新しいスレッド(new runnable(){public void run(){while(true){synchronized(p){p.get();}}}}})。start(); }} / * lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv zhang san .... male zhang san .... male Zhanウェイクアップメカニズムを待っています
/**スレッド待機メカニズム*待機とウェイクアップは同じロックでなければなりませんpublic static void main(string [] args){class person {public string name;プライベートストリングジェンダー; public void set(string name、string gender){this.name = name; this.gender = gender; } public void get(){system.out.println(this.name+"...."+this.gender); }}最終人p = new person();新しいスレッド(new runnable(){public void run(){int x = 0; while(true){synchronized(p){if(flags)try {p.wait();} catch(arturtedexception e){// todo auto-generated catch block e.printstacktrace();}; } else {"lili"、 "nv");新しいスレッド(new runnable(){public void run(){while(true){synchronized(p){if(!flags)try {p.wait();} catch(arternedexception e){// todo auto-enerated catch block e.printstacktrace(); })。始める(); }}生産および消費メカニズム1
public class threaddemo4 {private static boolean flags = false; public static void main(string [] args){class goods {private string name; private int num; public同期voidプロデュース(string name){if(flags)try {wait(); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } this.name = name+"number:"+num ++; System.out.println( "produced ......"+this.name); flags = true; notifyall(); } public synchronized void consust(){if(!flags)try {wait(); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } system.out.println( "消費*****"+name); flags = false; notifyall(); }}最終財g = new Goods();新しいスレッド(new runnable(){public void run(){while(true){g.produce( "product");}}})。start();新しいスレッド(new runnable(){public void run(){while(true){g.consume();}}})。start(); }}生産および消費メカニズム2
public class threaddemo4 {private static boolean flags = false; public static void main(string [] args){class goods {private string name; private int num; public synchronized void produce(string name){while(flags)try {wait(); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } this.name = name+"number:"+num ++; system.out.println(thread.currentthread()。getname()+"drocued ..."+this.name); flags = true; notifyall(); } public synchronized void consume(){while(!flags)try {wait(); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } system.out.println(thread.currentThread()。getName()+"消費*******"+name); flags = false; notifyall(); }}最終財g = new Goods();新しいスレッド(new runnable(){public void run(){while(true){g.produce( "product");}}}}}}}}}}}}}、}}}}、 "produce(" product ");}}}}}} }、 "Consumer No. 1")消費された*******商品番号:48050Producer No.1生産...コモディティ番号:48051COSSUMER NO.2消費****商品番号:48051Producer No. 2が生産しました...コモディティ番号:48052Consumer No. 2消費*** 48053COSSUMER No. 1が消費されました*******商品番号:48053Producer No. 1が生産されました...コモディティ番号:48054COSSUMER No. 2が消費されました。 48055*/上記は、Javaマルチスレッド情報の編集です。将来、関連する知識を追加し続けます。このサイトへのご支援ありがとうございます!