<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            java語言

            JAVA多線程之線程間的通信方式解析

            時間:2025-06-06 01:38:20 java語言 我要投稿
            • 相關推薦

            JAVA多線程之線程間的通信方式解析

              一,介紹

              本總結我對于JAVA多線程中線程之間的通信方式的理解,主要以代碼結合文字的方式來討論線程間的通信,故摘抄了書中的一些示例代碼。

              二,線程間的通信方式

              ①同步

              這里講的同步是指多個線程通過synchronized關鍵字這種方式來實現線程間的通信。

              參考示例:

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            public class MyObject {
             
              synchronized public void methodA() {
                //do something....
              }
             
              synchronized public void methodB() {
                //do some other thing
              }
            }
             
            public class ThreadA extends Thread {
             
              private MyObject object;
            //省略構造方法
              @Override
              public void run() {
                super.run();
                object.methodA();
              }
            }
             
            public class ThreadB extends Thread {
             
              private MyObject object;
            //省略構造方法
              @Override
              public void run() {
                super.run();
                object.methodB();
              }
            }
             
            public class Run {
              public static void main(String[] args) {
                MyObject object = new MyObject();
             
                //線程A與線程B 持有的是同一個對象:object
                ThreadA a = new ThreadA(object);
                ThreadB b = new ThreadB(object);
                a.start();
                b.start();
              }
            }

              由于線程A和線程B持有同一個MyObject類的對象object,盡管這兩個線程需要調用不同的方法,但是它們是同步執行的,比如:線程B需要等待線程A執行完了methodA()方法之后,它才能執行methodB()方法。這樣,線程A和線程B就實現了 通信。

              這種方式,本質上就是“共享內存”式的通信。多個線程需要訪問同一個共享變量,誰拿到了鎖(獲得了訪問權限),誰就可以執行。

              ②while輪詢的方式

              代碼如下:

              ?

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            60
            61
            62
            63
            64
            65
            66
            67
            68
            69
            70
            71
            72
            73
            74
            75
            76
            77
            78
            79
            80
            81
            82
            83
            import java.util.ArrayList;
            import java.util.List;
             
            public class MyList {
             
              private List<String> list = new ArrayList<String>();
              public void add() {
                list.add("elements");
              }
              public int size() {
                return list.size();
              }
            }
             
            import mylist.MyList;
             
            public class ThreadA extends Thread {
             
              private MyList 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("添加了" + (i + 1) + "個元素");
                    Thread.sleep(1000);
                  }
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }
            }
             
            import mylist.MyList;
             
            public class ThreadB extends Thread {
             
              private MyList list;
             
              public ThreadB(MyList list) {
                super();
                this.list = list;
              }
             
              @Override
              public void run() {
                try {
                  while (true) {
                    if (list.size() == 5) {
                      System.out.println("==5, 線程b準備退出了");
                      throw new InterruptedException();
                    }
                  }
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }
            }
             
            import mylist.MyList;
            import extthread.ThreadA;
            import extthread.ThreadB;
             
            public class Test {
             
              public static void main(String[] args) {
                MyList service = new MyList();
             
                ThreadA a = new ThreadA(service);
                a.setName("A");
                a.start();
             
                ThreadB b = new ThreadB(service);
                b.setName("B");
                b.start();
              }
            }

              在這種方式下,線程A不斷地改變條件,線程ThreadB不停地通過while語句檢測這個條件(list.size()==5)是否成立 ,從而實現了線程間的通信。但是這種方式會浪費CPU資源。之所以說它浪費資源,是因為JVM調度器將CPU交給線程B執行時,它沒做啥“有用”的工作,只是在不斷地測試 某個條件是否成立。就類似于現實生活中,某個人一直看著手機屏幕是否有電話來了,而不是: 在干別的事情,當有電話來時,響鈴通知TA電話來了。

              ③wait/notify機制

              代碼如下:

              ?

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            60
            61
            62
            63
            64
            65
            66
            67
            68
            69
            70
            71
            72
            73
            74
            75
            76
            77
            78
            79
            80
            81
            82
            83
            84
            85
            86
            87
            88
            89
            90
            91
            92
            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 (InterruptedException 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("已經發出了通知");
                      }
                      System.out.println("添加了" + (i + 1) + "個元素!");
                      Thread.sleep(1000);
                    }
                  }
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }
            }
             
            public class Run {
             
              public static void main(String[] args) {
             
                try {
                  Object lock = new Object();
             
                  ThreadA a = new ThreadA(lock);
                  a.start();
             
                  Thread.sleep(50);
             
                  ThreadB b = new ThreadB(lock);
                  b.start();
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }
            }

              線程A要等待某個條件滿足時(list.size()==5),才執行操作。線程B則向list中添加元素,改變list 的size。

              A,B之間如何通信的呢?也就是說,線程A如何知道 list.size() 已經為5了呢?

              這里用到了Object類的 wait() 和 notify() 方法。

              當條件未滿足時(list.size() !=5),線程A調用wait() 放棄CPU,并進入阻塞狀態。---不像②while輪詢那樣占用CPU

              當條件滿足時,線程B調用 notify()通知 線程A,所謂通知線程A,就是喚醒線程A,并讓它進入可運行狀態。

              這種方式的一個好處就是CPU的利用率提高了。

              但是也有一些缺點:比如,線程B先執行,一下子添加了5個元素并調用了notify()發送了通知,而此時線程A還執行;當線程A執行并調用wait()時,那它永遠就不可能被喚醒了。因為,線程B已經發了通知了,以后不再發通知了。這說明:通知過早,會打亂程序的執行邏輯。

            【JAVA多線程之線程間的通信方式解析】相關文章:

            Java多線程通信方法05-18

            java的多線程04-09

            java多線程05-11

            java多線程-線程通信實例詳細解讀07-07

            java多線程教程04-22

            java語言的多線程04-19

            java多線程介紹05-28

            Java多線程的線程守護例子06-08

            Java多線程的用法介紹03-29

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院