java多線程中斷學習

來源:互聯網
上載者:User

來至《java多線程設計模式》

1.wait

   (1)調用wait方法必須先獲得對象執行個體的鎖;

   (2)可以再synchronized方法中,或synchronized塊中或兩者調用的別的方法中;

   (3)執行wait方法的線程會進入obj的wait set裡面,進入之後就已經釋放obj的鎖;

   (4)被notify或notifyAll所喚醒的線程會前進到wait的下一個語句。

2.nofify和notifyAll

  (1)從obj的wait set中喚醒一個或所有線程(它們試圖去擷取obj的鎖),但是喚醒它(們)之後,該線程仍未釋放該鎖

  (2)wait,notify,notifyAll為object類的方法,對執行個體的wait set進行操作。

3.sleep

  (1)為線程類方法,讓線程進入阻塞狀態,得不到CPU時間,時間一過重新進入可執行狀態。但sleep方法不會釋放對象的鎖。

  (2)只能控制當前正在啟動並執行線程。

4.yield

  (1)暫停當前正在執行的線程對象,並執行其他線程,讓當前啟動並執行線程回到可運行狀態,並允許具有相同優先順序的其他線程獲得運行機會。

  (2)但它可能未讓步而重新被發送器選中。

5.join

  (1)讓一個線程B加入到另一個線程A的尾部。

  (2)A執行完畢之前,B不能工作。

 

二、調用interrupt()的影響:

1.對sleep

   任何線程在任何時刻都可以調用其他線程的interrupt方法,被interrupt後放棄暫停狀態,拋出異常。

2.對wait

  若obj已經在wait set中,interrupt方法會使線程重新獲得鎖再拋出異常,若未能獲得鎖定,則無法拋出異常。

  執行interrupt時無需獲得對該線程的鎖定。

3.join

  調用joion方法,無需獲得鎖定,馬上跳到catch塊裡。

 

三、調用interrupt方法不一定會拋出interruptException:

   (1)若調用時,不是在執行sleep/wait/join則不會拋出異常,只是改變中斷狀態;

   (2)若調用時,是在執行sleep/wait/join則拋出異常。

 

  //  作業    private void doWork() throws InterruptedException {        counter++;        System.out.println("doWork: counter = " + counter);        try {            Thread.sleep(500);        } catch (InterruptedException e) {        }    }

以上若調用interrupt則無法中斷。

System.out.println("main: shutdownRequest");            t.shutdownRequest();

必須如下:

// 作業    private void doWork() throws InterruptedException {        counter++;        System.out.println("doWork: counter = " + counter);        Thread.sleep(500);    }

則可以正常終止。

在調用doWork的地方進行捕獲:

  // 動作    public void run() {        try {            while (!isInterrupted()) {                doWork();            }        } catch (InterruptedException e) {        } finally {            doShutdown();        }    }
 // 終止請求    public void shutdownRequest() {        interrupt();    }
 

上面那個捕獲異常之後沒有處理,所以在run裡面無法捕獲,無法執行doShutdown方法來停止。

 

對比:

  public synchronized Request getRequest() throws InterruptedException {        while (queue.size() <= 0) {            wait();        }        return (Request)queue.removeFirst();    }

這裡拋出異常,同時在調用的地方進行捕獲,並且退出run

public void run() {        try {            for (int i = 0; i < 10000; i++) {                Request request = new Request("No." + i);                System.out.println(Thread.currentThread().getName() + " requests " + request);                requestQueue.putRequest(request);                Thread.sleep(random.nextInt(1000));            }        } catch (InterruptedException e) {        }    }

調用時,是直接interrupt:

   //呼叫interrupt方法        System.out.println("***** calling interrupt *****");        alice.interrupt();        bobby.interrupt();

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.