Thread线程notify方法的自我理解

感谢博主:http://zy19982004.iteye.com/blog/1626916 这篇博文给予我线程知识很大的帮助

知识背景:(1)wait()、notify()均是Object的方法,故每个对象都拥有这2个方法。

     (2)obj.wait、obj.notify必须在synchronized(obj){}代码块内部使用

     (3)obj.wait会抛异常,obj.notify没有异常抛出

     (4)2个线程同时运行,线程1执行到obj.wait()代码时,线程阻塞,释放对象锁;线程2拿到对象锁,线程2执行到obj.notify()代码时,唤醒线程1,线程1进入锁池,此时线程2并未释放对象锁,代码继            续obj.notify()往下走,走完synchronized代码块后,线程2释放对象锁;线程2进入锁池中与线程1一起参与资源(对象锁)争抢。

     (5)下面的例子中,如果线程1(生产者)obj.notify();代码注释掉,会出现线程死锁。原因:线程2执行到obj.wait(),线程2进入等待队列中;线程1,拿到对象锁,走完代码块,因为线程2还是等待,线程1一定拿到对象锁,然后执行了obj.wait();2个线程都等待了,线程死锁。

class Info {
    private String name;
    private String content;
    private boolean flag;
    public boolean isFlag() {
        return flag;
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}
class Producer implements Runnable {
    private Info info;
    public Producer(Info info) {
        this.info = info;
    }
    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        boolean flag = false;
        for (int i = 0; i < 10; i++) {
            if (!flag) {
                synchronized (info) {
                    if (info.isFlag()) {
                        try {
                            System.out.println("有产品(MLDN),生产者等待消费....");
                            info.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    this.info.setName("李兴华");
                    try {
                        Thread.sleep(90);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    this.info.setContent("教学老师 + " + i);
                    flag = true;
                    info.setFlag(true);
                    System.out.println("set()--李兴华&&java讲师 flag="
                            + info.isFlag());
                    info.notify();
                }
            } else {
                synchronized (info) {
                    if (info.isFlag()) {
                        try {
                            System.out.println("有产品(李兴华),生产者等待消费....");
                            info.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    this.info.setName("MLDN");
                    try {
                        Thread.sleep(90);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    this.info.setContent("WWW.MLDN.CN + " + i);
                    flag = false;
                    info.setFlag(true);
                    System.out.println("set()--MLDN&&WWW.MLDN.CN flag="
                            + info.isFlag());
                    info.notify();
                }
            }
        }
    }
}
class Consumer implements Runnable {
    private Info info;
    public Consumer(Info info) {
        this.info = info;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (info) {
                if (!info.isFlag()) {
                    try {
                        System.out.println("没有产品,等待生产....");
                        info.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.print(this.info.getName() + "————>");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(this.info.getContent() + "--" + i);
                info.setFlag(false);
                info.notify();
            }
        }
    }
}
public class Test_producer_consumer {

    public static void main(String[] args) {
        Info info = new Info();
        Producer p = new Producer(info);
        Consumer c = new Consumer(info);
        Thread t1 = new Thread(p, "p");
        Thread t2 = new Thread(c, "c");
        t1.start();
        t2.start();
    }
}

结果有上面2种,第一种,当线程1运行到obj.notify();//a处,线程2被唤醒,线程2进入竞争obj对象的锁池。线程1执行完synchronized代码块后,释放对象锁;如果线程1不再参与对象锁的竞争那么结果2中的情况不会发生;但是结果2发生了,线程1再一次拿到对象锁,然后执行到obj.wait()方法后,释放对象锁,线程1进入阻塞状态,线程2获得对象锁。

 

这个结果是去掉消费者Thread.sleep(5000);得到的一种结果。2个1出现说明,线程1调用obj.notify()后,线程1再一次参与了对象锁的竞争,并且获得到了。

转载于:https://www.cnblogs.com/jiaqingblog/p/6278291.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值