wait()和notify()

1.notify

public final void notify()

       唤醒正在等待对象监视器的单个线程。 如果任何线程正在等待这个对象,其中一个被选择被唤醒。 选择是任意的,并且由实施的判断发生。 线程通过调用wait方法之一等待对象的监视器。

       唤醒的线程将无法继续,直到当前线程放弃此对象上的锁定为止。 唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能正在积极地竞争在该对象上进行同步; 例如,唤醒的线程在下一个锁定该对象的线程中没有可靠的权限或缺点。

注意:该方法只能由作为该对象的监视器的所有者的线程调用

 

2.wait

public final void wait()
                throws InterruptedException

导致当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法。 换句话说,这个方法的行为就好像简单地执行呼叫wait(0) 。

当前的线程必须拥有该对象的显示器。 该线程释放此监视器的所有权,并等待另一个线程通知等待该对象监视器的线程通过调用notify方法或notifyAll方法notifyAll 。 然后线程等待,直到它可以重新获得监视器的所有权并恢复执行。

package com.xcl_O;

import java.util.Calendar;

/**
 * 3. 银行存取款
 * 要求:
 * 小明打算去提款机上取钱, 发现卡上没有钱,这时候他告知妈妈去存钱,妈妈存了钱了,告知小明存好了可以取钱了。
 *     小明分多次取钱,每次取100,当发现钱不够100,就等妈妈存钱
 *     妈妈每次存钱2000,当发现钱小于100就存钱,并且通知小明取取钱,当大于100就等小明钱不够再存
 */
class  B {//先造一个对象来作为桥梁(让两个线程都可以使用次对象以便达到操作统一对象)
    private String name;//没得用
    private  Boolean  Cun;//为了判断是否先要钱还是先存钱
    private  int money;//初始化值
    public Boolean getCun() {
        return Cun;
    }
    public Boolean isCun() {
        return Cun;
    }
    public int getMoney() {
        return money;
    }
    public void setMoney(int money) {
        this.money = money;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setCun(Boolean cun) {
        Cun = cun;
    }
    public B(String name) {
        this.name = name;
    }
    public B(String name, Boolean cun, int money) {//构造函数就是为了传参
        this.name = name;
        Cun = cun;
        this.money = money;
    }
    @Override
    public String toString() {
        return "B{" + "name='" + name + '\'' + ", Cun=" + Cun + ", money=" + money + '}';
    }
}
class Son implements Runnable{
    private  B b;
    public Son(B b) {
        this.b = b;
    }
    @Override
    public void run() {
        while (true) {//死循环
            synchronized (b) {//为了锁对象来进行进入的对象保持一致性
                if (! b.isCun()){//如果为false 则进入程序
                    if (b.getMoney()>= 100){//判断钱数是否是小于100 如果不是小于100 则进入大廓号的语句

                        b.setMoney(b.getMoney()-100);
                        System.out.println(Thread.currentThread().getName() +"取了100元" +", 还剩:" +b.getMoney()+"元。 取款日期为:"+Calendar.getInstance().getTime());
                        //获取当前线程对象sout的名字和金钱信息等等。。。

                    }else {
                        b.setCun(true);//如果金钱数小于一百元则执行该语句 然后将Cun属性赋值为true
                        // 然后唤醒妈妈然后昂妈妈存钱
                        b.notify();

                    }
                }else  {
                    try {
                        b.wait();//等待着被唤醒让妈妈线程先执行,妈妈存完钱之后就会唤醒我
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
class Monther implements Runnable{
    private  B b;//将类对象作为一个属性

    public Monther(B b) {//为了传参数
        this.b = b;
    }
    @Override
    public void run() {
        while (true){//死循环
        synchronized (b) {//锁是为了保证对象的一致性
            if (b.isCun()){//如果为true则执行该语句
                if (b.getMoney() < 100){//当钱数小于100时 执行下面语句
                    b.setMoney(2000);//需要给儿子增加2000元
                    System.out.println(Thread.currentThread().getName()+"已经存上"+b.getMoney()+"元");
                }else {
                    b.setCun(false);//将二千元存进去之后 就来将CUN 变为false 然后
                    b.notify();//就要唤醒儿子 让儿子去花钱
                    try {
                        Thread.sleep(1000);//为了省钱就去将时间设为1秒钟
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }else {
                try {//然后就等待被唤醒(儿子花完钱就会唤醒我)这是等待的时间就是儿子花钱的时间
                    b.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    }
                 }
            }
        }
    }
}
public class Demo1 {
    public static void main(String[] args)  {
        B b = new B("小明",true,500);//先new一个对象来作为桥梁
        Son son = new Son(b);//儿子对象
        Thread thread = new Thread(son,"小明");//儿子线程
        thread.start();//启动儿子线程
        Monther monther  = new Monther(b);//new 一个妈妈对象
        Thread thread1 = new Thread(monther,"妈妈");//妈妈线程
        thread1.start();//启动妈妈线程
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值