<ruby id="bdb3f"></ruby>

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

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 線程間通信 [TOC] 在我們之前的例子中,我們存在一個問題。當我們的賬戶余額不夠了怎么辦?我們就需要等待存入足夠的錢后才能去處理。接下來,我們采用一個更直觀更經典的一個例子說明 ## 經典案例-生產者與消費者 ![](https://img.kancloud.cn/36/17/3617a8a3da5d53d93e181689aa7fdc62_651x327.png) ~~~java public class Queue { private int n; public synchronized int getN() { System.out.println("消費:" + n); return n; } public synchronized void setN(int n) { System.out.println("生產:" + n ); this.n = n; } } ~~~ ~~~java public class Producer implements Runnable{ //共享queue類 Queue queue; public Producer(Queue queue) { this.queue = queue; } @Override public void run() { int i = 0; while(true) { i++; //對queue類中的n進行賦值 queue.setN(i); //模擬實際生產中線程被打斷 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } ~~~ ~~~java public class Consumer implements Runnable{ Queue queue; public Consumer(Queue queue) { this.queue = queue; } @Override public void run() { while(true) { queue.getN(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } ~~~ ~~~java public class PCTest { public static void main(String[] args) { Queue queue = new Queue(); Producer pd = new Producer(queue); Consumer cs = new Consumer(queue); Thread threadP = new Thread(pd); Thread threadC = new Thread(cs); threadP.start(); threadC.start(); } } ~~~ 本案例實現了一個基礎的線程交互模型,但是通過執行結果,可以發現程序中存在兩個問題。 1. **數據錯位** 如果沒有采用同步的話,生產者線程剛剛生產了數據,但是消費者線程取出的數據卻不是剛剛生產出來的數據 2. **重復操作** 生產者生產了若干的數據,消費者才開始取出數據;或者是消費者去完一個數據后又接著取出數據。 ## Object線程等待與喚醒 重復操作問題的解決,需要引入線程的等待與喚醒機制,而這一機制我們可以通過Object類完成。 >[info]Object類中定義有線程的等待與喚醒支持。我們主要要掌握Object類中的`wait()`,`notify()`,`notifyAll()`三個方法。 | 方法 | 說明 | | :---: | :---: | | public final void wait() throws InterruputedException | 線程的等待 | | public final void wait(long timeout) throws InterruputedException | 設置線程等待毫秒數 | | public final void wait(long timeout,int nanos) throws InterruputedException | 設置線程等待毫秒數和納秒數 | | public final void notify() | 喚醒某一個等待線程,使其結束等待 | | public final void notifyAll() | 喚醒全部等待線程,使它們結束等待 | **接下來,修改一下我們的程序吧** ~~~java public class Queue { private int n; boolean flag = false; public synchronized int getN() { if(!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("消費:" + n); flag = false;//消費完畢,容器中沒有數據 return n; } public synchronized void setN(int n) { if(flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("生產:" + n ); this.n = n; flag = true;//生產完畢,容器中已經有數據 } } ~~~ 在我們修改完這樣的程序后,我們會發現我們的程序有可能會進入一個死鎖狀態。因為我們在代碼中沒有明確的喚醒處于等待狀態的線程。 ~~~java public class Queue { private int n; boolean flag = false; public synchronized int getN() { if(!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("消費:" + n); flag = false;//消費完畢,容器中沒有數據 notifyAll(); return n; } public synchronized void setN(int n) { if(flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("生產:" + n ); this.n = n; flag = true;//生產完畢,容器中已經有數據 notifyAll(); } } ~~~
                  <ruby id="bdb3f"></ruby>

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

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看