Java Multi-Threaded形式のスレッド間の通信に関する私の理解のこの要約は、主にテキストと組み合わせたコードのスレッド間の通信について説明しています。したがって、私は本のいくつかの例コードを抜粋しました、そして、特定のコンテンツは次のとおりです
①同期
ここで説明する同期は、同期されたキーワードを使用してスレッド間の通信を実現する複数のスレッドを指します。
参照例:
public class myobject {同期public public void methoda(){// do something ....}同期public void methodb(){// other other thins}} public class threada extends swrep {private myobject object; // constructor @override @override public void run(){super.run(); object.methoda(); }} public class threadb拡張スレッド{private myobject object; // constructor @override public void run(){super.run(); object.methodb(); }} public class run {public static void main(string [] args){myobject object = new Myobject(); //スレッドAとスレッドbは同じオブジェクトを保持します:オブジェクトスレッドa = new Threada(object); threadb b = new shoodb(object); a.start(); b.Start(); }}スレッドAとスレッドBは同じMyobjectクラスのオブジェクトオブジェクトを保持するため、これらの2つのスレッドは異なる方法を呼び出す必要がありますが、それらは同期して実行されます。たとえば、スレッドBは、MethodB()メソッドを実行する前に、Thread AがMethoda()メソッドを実行するのを待つ必要があります。このようにして、スレッドAとスレッドBはコミュニケーションを実現します。
この方法は、本質的に「共有メモリ」通信です。複数のスレッドが同じ共有変数にアクセスする必要があり、ロックを取得する人(アクセス権が取得されます)は、それを実行できます。
pollingポーリング方法
コードは次のとおりです。
import java.util.arraylist; import java.util.list; public class mylist {private list <string> list = new arraylist <string>(); public void add(){list.add( "要素"); } public int size(){return list.size(); }} import mylist.mylist; public class threada extends thread {privatemylist list; public threada(mylist list){super(); this.list = list; } @Override public void run(){try {for(int i = 0; i <10; i ++){list.add(); System.out.println( "addd" +(i + 1) + "elements"); thread.sleep(1000); }} catch(arturnedexception e){e.printstacktrace(); }}} import mylist.mylist; public class threadb extends thread {private mylist list; public Streadb(mylist list){super(); this.list = list; } @Override public void run(){try {while(true){if(list.size()== 5){system.out.println( "== 5、thread bはexitの準備ができています"); new interruptedexception(); }}} catch(arturnedexception e){e.printstacktrace(); }}} import mylist.mylist; import extthread.threada; import extthread.threadb; public static void main(string [] args){mylist service = new Mylist(); threada a = new Streada(service); a.setname( "a"); a.start(); threadb b = new StreadB(service); B.SetName( "B"); b.Start(); }}このようにして、スレッドaは条件を絶えず変化させ、スレッドスレッドBはこの条件(list.size()== 5)がwhileステートメントを通じて真であるかどうかを絶えず検出し、それによってスレッド間のコミュニケーションを実現します。しかし、この方法はCPUリソースを無駄にします。それがリソースを無駄にする理由は、JVMスケジューラが実行のためにBをスレッドBに渡すと、「有用な」作業を行うことはないが、特定の条件が真であるかどうかを常にテストしているからです。それは実生活に似ていますが、誰かが携帯電話が携帯電話の画面に表示されているかどうかを見続けています。他のことをするのではなく、電話が来るとき、電話が来ていることを彼に通知します。スレッドポーリングの影響については、次のことを参照してください:Javaでデッドループを実行するスレッドの結果は何ですか
wait/通知メカニズム
コードは次のとおりです。
import java.util.arraylist; import java.util.list; public class mylist {private static list <string> list = new ArrayList <String>(); public static void add(){list.add( "anystring"); } public static int size(){return list.size(); }} public class threada extends thread {private object lock; public threada(object lock){super(); this.lock = lock; } @Override public void run(){try {synchronized(lock){if(mylist.size()!= 5){system.out.println( "wait begin" + system.currenttimemillis()); lock.wait(); system.out.println( "wait end" + system.currenttimemillis()); }}} catch(arturnedexception e){e.printstacktrace(); }}} public class threadb extends thread {private object lock; public threadb(object lock){super(); this.lock = lock; } @Override public void run(){try {synchronized(lock){for(int i = 0; i <10; i ++){mylist.add(); if(mylist.size()== 5){lock.notify(); system.out.println( "notified"); } system.out.println( "addd" +(i + 1) + "elements!"); thread.sleep(1000); }}} catch(arturnedexception e){e.printstacktrace(); }}} public class run {public static void main(string [] args){try {object lock = new object(); threada a = new Streada(lock); a.start(); thread.sleep(50); threadb b = new SthreadB(lock); b.Start(); } catch(arturnedexception e){e.printstacktrace(); }}}操作を実行する前に、特定の条件が満たされるのを待つ必要があります。スレッドBはリストに要素を追加し、リストのサイズを変更します。
AとBはどのように通信しますか?言い換えれば、Thread aはlist.size()がすでに5であることをどのように知っていますか?
ここでは、オブジェクトクラスのwait()およびnotify()メソッドを使用します。
条件が満たされない場合(list.size()!= 5)、CPUを放棄するためにwait()を呼び出してブロッキング状態に入ります。 ---ポーリングのようにCPUを取り上げないでください
条件が満たされると、スレッドBはnotify()を呼び出してスレッドAを通知します。
この方法の利点の1つは、CPUの使用率が改善されたことです。
ただし、いくつかの欠点があります。たとえば、スレッドBは最初に実行され、一度に5つの要素を追加し、Notify()を呼び出して通知を送信し、スレッドAはまだ実行されます。スレッドAが実行され、wait()を呼び出すと、目覚めなくなります。スレッドBはすでに通知を発行しており、将来通知を発行しないためです。これは、通知が早すぎて、プログラムの実行ロジックを混乱させることを示しています。
上記はこの記事に関するものです。誰もがJavaプログラミングを学ぶことが役立つことを願っています。