通过一个例子,描述线程wait和notify方法

场景:一个类中,一个是往容器中添加元素的方法,一个是返回容器大小的方法,现在又两个线程,A线程调用添加方法,B线程调用返回容器大小方法,当大小为5的时候,B线程提示并结束。

代码可直接复制,运行:

public class UseWaitAndNotify {
    volatile List list = new ArrayList();//这里为什么使用volatile,请看:https://my.oschina.net/u/4049911/blog/3121294  
    public void add(Object o) {
        list.add(o);
    }
    public int size() {
        return list.size();
    }
    public void useWaitAndNotify() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    System.out.println("size方法开始");
                    /**
                     * 这里必须得是不等于5,因为刚开始肯定不等于5,然
                     * 后才会进这个方法,执行wait方法,这个线程就会在
                     * wait那等着。
                     * 然后cpu执行另一个方法,当另一个方法执行等于5
                     * 是,使用notify唤醒等待的线程(等待同一个锁的线
                     * 程)。
                     * 然后从wait方法开始往下执行,到结束。
                     */
                    if(list.size()!=5) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    System.out.println("size方法结束");
                }
            }
        }).start();
        synchronized (this) {
            System.out.println("add方法开始");
            for(int i=0;i<10;i++) {
                /**
                 *当加入元素==5时,当前线程就应该停止,让出cpu,让cpu
                 去执行其他线程。
                 *那让线程让出cpu的方法有哪些呢:
                 *wait让出线程,释放锁
                 *yield 让出cpu,但不会释放锁
                 *join 插入其他线程,线程同步作用,在被调用线程未结束
                 前,当前线程将一直阻塞在join处
                 *
                 *我们使用wait
                 *
                 */
                list.add(new Object());
                if(i==4) {
                    /**
                     * 这里为什么使用notify后,又使用wait呢,就是上面
                     * 这个方法的意思,使用notify,当前线程是不会释放
                     * 锁的,所以即使唤醒了其他线程,其他线程拿不到
                     * 锁,也执行不了。
                     * 也就是说如果下面不使用wait,当list等于5的时
                     * 候,另一个线程拿不到锁,执行不了,只有当前线程
                     * 释放锁,另一个线程才会拿到锁执行,
                     * 也就是说当list的size等于10的时候,另一个线程才
                     * 会停止
                     */
                    this.notify();
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println("add方法结束");
            }
        }
    }

    @Test
    public void test() {  
        //使用wait和notify实现  
        useWaitAndNotify();  
    }  
}

因为wait和notify只能在锁中使用,所以需要加上synchronized锁,而为什么必须要在锁中只用呢,请自行google

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值