多线程模型其实用得最多的就是生产者-消费者模式,其实如今流行的异步执行也是在这基础上发展起来的。其实问题的关键就是一句话,如何保证多线程任务可以按必定的顺序执行,由于实际的问题每每有必定的逻辑顺序,也就是先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(); } } } } } } }