多線程模型其實用得最多的就是生產者-消費者模式,其實如今流行的異步執行也是在這基礎上發展起來的。其實問題的關鍵就是一句話,如何保證多線程任務可以按必定的順序執行,由於實際的問題每每有必定的邏輯順序,也就是先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(); } } } } } } }