wait()和notify()

package concurrent._wait_notify;

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        ThreadA a = new ThreadA("A");
        synchronized (a){
            System.out.println("开始主线程睡眠3000ms");
            Thread.sleep(3000);
            System.out.println("启动a");

            a.start();
            System.out.println("开始主线程睡眠5000ms");
            Thread.sleep(5000);

            System.out.println("主线程wait");
            a.wait();
            System.out.println("主线程刚从阻塞队列出来,马上结束了");
        }

    }
}

class ThreadA extends  Thread{
    public ThreadA(String name){
        super(name);
    }

    @Override
    public void run() {
        System.out.println("尝试获得this锁");
        synchronized (this){
            System.out.println("获得了this锁,准备notify");
            this.notify();
            System.out.println("notify()成功");
        }
    }
}

结果:

开始主线程睡眠3000ms
启动a
开始主线程睡眠5000ms
尝试获得this锁
主线程wait
获得了this锁,准备notify
notify()成功
主线程马上结束了

 

 

修改代码:

package concurrent._wait_notify;

public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();

        ThreadB b1 = new ThreadB("b1",obj);
        ThreadB b2 = new ThreadB("b2",obj);
        ThreadB b3 = new ThreadB("b3",obj);

        b1.start();
        b2.start();
        b3.start();

        Thread.sleep(1000);
        synchronized (obj){
            obj.notifyAll();
        }
    }


}

class ThreadB extends  Thread{
    private Object obj;
    public ThreadB(String name,Object obj){
        super(name);
        this.obj = obj;
    }

    @Override
    public void run() {
        String threadName = this.getName();
        System.out.println(threadName +"尝试获得obj锁");
        synchronized (obj){
            try {
                System.out.println(threadName+"获得了obj锁,进入wait");
                obj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(threadName+"从wait出来了");
        }
    }
}

结果:

b2尝试获得obj锁
b2获得了obj锁,进入wait
b3尝试获得obj锁
b3获得了obj锁,进入wait
b1尝试获得obj锁
b1获得了obj锁,进入wait
b1从wait出来了
b3从wait出来了
b2从wait出来了

再次修改代码将Thread.sleep(1000)注释掉

 

结果显示:

b1尝试获得obj锁
b1获得了obj锁,进入wait
b2尝试获得obj锁
b3尝试获得obj锁
Main函数获得了锁,进行notifyAll操作
b1从wait出来了
b3获得了obj锁,进入wait
b2获得了obj锁,进入wait

这个结果就是,获得锁的顺序是,b1,main,b2,b3。(打印顺序,不能反映cpu获得锁的顺序,只能说明打印的顺序)

当main函数执行完成notifyAll()之后,b1从阻塞队列出来,结束运行,这时候b2,b3再次进入阻塞状态,但是却没有别的进程将他们唤醒,就会一直阻塞。

 

notify操作,实际上是释放基于某个锁上面的wait的线程,是根据锁来释放的。

wait操作是让当前在cpu运行的线程,基于某个锁上wait,便于基于某个锁上唤醒。

 

文章参考博客:

http://www.cnblogs.com/xingele0917/p/3979494.html

posted @ 2018-11-23 14:30  式微胡不归  阅读(213)  评论(0编辑  收藏  举报