<address id="ousso"></address>
<form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
  1. JAVA多線程之線程間的通信方式解析

    時間:2025-08-22 01:26:31 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() {
        /pic/code>
      }
     
      synchronized public void methodB() {
        /pic/code>
      }
    }
     
    public class ThreadA extends Thread {
     
      private MyObject object;
    /pic/code>
      @Override
      public void run() {
        super.run();
        object.methodA();
      }
    }
     
    public class ThreadB extends Thread {
     
      private MyObject object;
    /pic/code>
      @Override
      public void run() {
        super.run();
        object.methodB();
      }
    }
     
    public class Run {
      public static void main(String[] args) {
        MyObject object = new MyObject();
     
        /pic/code>
        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多線程通信方法12-16

    java的多線程11-04

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

    java多線程10-24

    java語言的多線程08-31

    java多線程介紹11-28

    java多線程教程07-07

    Java多線程的線程守護例子01-11

    如何使用java多線程10-09

    • 相關推薦
    <address id="ousso"></address>
    <form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
    1. 日日做夜狠狠爱欧美黑人