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();
                        }
                    }
                }
            }
        }
    }
}
相关文章
相关标签/搜索