java 线程通信通信_java中线程通信(传统的线程通信)

假设现在系统有两个线程,这两个线程分别代表存款者和取钱者——现在假设系统有一种特殊的要求,系统要求存款者和取钱者不断地重复存款、取钱的动作。而且要求每当存款者将钱存入指定账户后,取钱者就立即取出该笔钱。不允许存款者连续两次存钱,也不允许取钱者连续两次取钱。

为了实现这种功能,可以借助Object类提供的wait()、notify()、notifyAll() 3 个方法,这3个方法并不属于Thread类,而是属于Object类。但这3 个方法必须由同步监视器对象来调用,这可分以下两种情况:

1、对于使用synchronized修饰的同步方法,因为该类的默认实例是(this)就是同步监视器。所以可以在同步方法中直接调用这3个方法。

2、对于使用synchronized修饰的同步代码块,同步监视器是synchronized后括号里的对象,所以必须使用该对象调用这3个方法。

关于这3个方法的解释如下:

wait():导致当前线程等待,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来唤醒该线程。该wait()方法有三种形式——无时间参数的wait(一直等待,知道其他线程通知),带毫秒参数的wait和带毫秒、毫微妙参数的wait(这两种方法都是等待指定时间后自动苏醒) 调用wait方法的当前线程会释放对该同步监视器的锁定。

notify():唤醒在次同步监视器上等待的单个线程。如果所有的线程都在此同步监视器上等待,则会选择唤醒其中一个线程。选择是任意的。只有当前线程放弃对该同步监视器的锁定后(使用wait方法),才可以执行被唤醒的线程。

notifyAll():唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对同步监视器的锁定后,才可以执行被唤醒的线程。

1 public classDrawTest{2 public static voidmain(String[] args){3 Account a=new Account("刘腾",10000);4 new DrawThread(a,100).start();5 new InThread(a,50).start();6 new InThread(a,60).start();7 new InThread(a,70).start();8 }9 }10 //账户类

11 classAccount{12 privateString name;13 private doublemoney;14 private boolean flag=false;15

16 publicAccount(){}17 public Account(String name,doublemoney){18 this.name=name;19 this.money=money;20 }21 public doublegetMoney(){22 returnmoney;23 }24 public synchronized void draw(doubledrawmoney){25 try{26 //如果flag为假,说明还没有人往里面存钱,所以让该线程等待。

27 if(!flag){28 wait();29 }else{30 System.out.println("取出钱数为:"+drawmoney+" 剩余钱数:"+(getMoney()-drawmoney));31 flag=false;32 notifyAll();33 }34 }catch(Exception e){System.out.println(e);}35 }36 public synchronized void deposit(doubleinmoney){37 try{38 if(!flag){39 System.out.println("存入钱数为:"+inmoney+" 目前的钱数为:"+(getMoney()+inmoney));40 flag=true;41 notifyAll();42 }else{43 wait();44 }45 }catch(Exception e){}46 }47 }48 //取钱线程

49 class DrawThread extendsThread{50 privateAccount account;51 private doubledrawmoney;52

53 public DrawThread (Account account,doubledrawmoney){54 this.account=account;55 this.drawmoney=drawmoney;56 }57 public voidrun(){58 for(int i=0;i<100;i++){59 account.draw(drawmoney);60 }61 }62 }63 class InThread extendsThread{64 privateAccount account;65 private doubleinmoney;66

67 public InThread(Account account,doubleinmoney){68 this.account=account;69 this.inmoney=inmoney;70 }71 public voidrun(){72 for(int k=0;k<100;k++){73 account.deposit(inmoney);74 }75 }76 }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值