wait()&nitifyAll()簡單工做調度

多線程模型其實用得最多的就是生產者-消費者模式,其實如今流行的異步執行也是在這基礎上發展起來的。其實問題的關鍵就是一句話,如何保證多線程任務可以按必定的順序執行,由於實際的問題每每有必定的邏輯順序,也就是先A再B(A->B)。生產者消費者就是如此,生產者不生產,消費者就沒有辦法消費,只有等生產者生產完成,消費者才能消費,不然就只能等待。可是對於多線程任務來講,卻不是如此,操做線程調度器保證每一個線程都有必定的機會被執行,可是不會保證調度的時機,天然也就保證不了邏輯順序。java

java中繼承自object類的wait(),notify()(notifyAll(),詳細區別還請百度)方法就是對線程調度的一種抽象。可是我並不推薦在實際工程中使用這樣的代碼,這種方式是一種低層次的抽象,實際寫出的代碼每每是不符合人的直覺且難以維護的,並且多線程的BUG每每是難以發現和修改的,這也正印證了一句我在不久前讀到的話:"併發編程每每是很困難的,即便是很簡單直觀的問題。"總之一句話,不要在工程中嘗試使用Object類的線程調度方法,若是有須要,還請使用java.util.concurrent.*編程

關於wait和noyify方法,網上不少資料都能查到,畢竟是從JDK1.0時代就有的方法。可是我仍是有幾點要說明:多線程

1.wait/notify只能在同步事後的代碼塊使用(即synchronize關鍵字修飾的block),要激活object對象的上述方法,當前線程必須持有該對象的鎖,也就是說synchronize指定哪一個對象,就必須調用哪一個對象的上述方法,若是synchronize修飾方法,則調用this對象的wait/notify;併發

2.wait方法主要有如下的做用:wait告訴JVM,你如今給個人對象我暫時處理不了(也許是不知足我須要的條件),這樣吧,我把對象讓出去,讓能作的先作了,到時候再通知我吧。異步

3.notify/notifyAll方法主要有如下做用:notify告訴JVM,剛剛我拿到了對象,而且該作的工做已經作完了,我如今把鎖交出去,大家接下來該幹嗎幹嗎把。ide

如下是兩個線程輪流打印A,B的代碼:this

public class MultiThreadTest {

    private boolean flag = true;
    private Object object = new Object();

    public static void main(String[] args) {
        new MultiThreadTest().test();
    }

    public void test() {
        new Thread(new A()).start();
        new Thread(new B()).start();
    }

    private void doSomething(String s, boolean flag) {
        System.out.println(s);
        this.flag = flag;
        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private class A implements Runnable {

        @Override
        public void run() {
            synchronized (object) {
                while (true) {
                    if (flag) {
                        doSomething("A", false);
                        object.notifyAll();
                    } else {
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        }
    }

    private class B implements Runnable {
        @Override
        public void run() {
            synchronized (object) {
                while (true) {
                    if (!flag) {
                        doSomething("B", true);
                        object.notifyAll();
                    } else {
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}
相關文章
相關標籤/搜索