线程的同步和协调

一 、用synchronized()来实现线程的同步,书上一个银行存取款的例子很明确

public class Example12_7 {
   public static void main(String args[]) {
      Bank bank = new Bank();
      bank.setMoney(200);
      Thread accountant,    //会计
             cashier;      //出纳
      accountant = new Thread(bank);
      cashier = new Thread(bank);
      accountant.setName("会计");
      cashier.setName("出纳");
      accountant.start();
      cashier.start(); 
   }
}


package thread;
public class Bank implements Runnable {
   int money=200;
   public void setMoney(int n) {
      money=n;
   }
   public void run() {
      if(Thread.currentThread().getName().equals("会计")) 
         saveOrTake(300);
      else if(Thread.currentThread().getName().equals("出纳"))
         saveOrTake(150);;
   }
    public synchronized void saveOrTake(int amount) { //存取方法
      if(Thread.currentThread().getName().equals("会计")) {
         for(int i=1;i<=3;i++) { 
             money=money+amount/3;      //每存入amount/3,稍歇一下
             System.out.println(Thread.currentThread().getName()+
                               "存入"+amount/3+",帐上有"+money+"万,休息一会再存");
             try { Thread.sleep(1000);  //这时出纳仍不能使用saveOrTake方法 
             }                       
             catch(InterruptedException e){}
         }
      }
      else if(Thread.currentThread().getName().equals("出纳")) {
         for(int i=1;i<=3;i++) { //出纳使用存取方法取出60
             money=money-amount/3;   //每取出amount/3,稍歇一下
             System.out.println(Thread.currentThread().getName()+
                               "取出"+amount/3+"帐上有"+money+"万,休息一会再取");
             try { Thread.sleep(1000);       //这时会计仍不能使用saveOrTake方法
             }                         
             catch(InterruptedException e){}
         }
      }
   }
}

二 、线程的协调同步
线程用wait()让出CPU使用权,待执行的程序完毕后调用nofity ()或notifyAll()来通知处于等待的线程结束等待并于断点处继续执行(notifyAll()是对全部,nofity ()是对个体)。

书上买电影票的例子我觉得很准却的描述了这个过程。

public class Example12_8 {
   public static void main(String args[ ]) {
      TicketHouse officer = new TicketHouse();
      Thread zhangfei,likui;
      zhangfei = new Thread(officer); 
      zhangfei.setName("张飞");
      likui = new Thread(officer);  
      likui.setName("李逵");
      zhangfei.start();
      likui.start();
   }
}


public class TicketHouse implements Runnable {
   int fiveAmount=2,tenAmount=0,twentyAmount=0; 
   public void run() {
      if(Thread.currentThread().getName().equals("张飞")) {
          saleTicket(20);
      }
      else if(Thread.currentThread().getName().equals("李逵")) {
          saleTicket(5);
      }
   }
   private synchronized void saleTicket(int money) {
       if(money==5) {  //如果使用该方法的线程传递的参数是5,就不用等待
        fiveAmount=fiveAmount+1; 
        System.out.println( "给"+Thread.currentThread().getName()+"入场卷,"+
                            Thread.currentThread().getName()+"的钱正好");
       }
       else if(money==20) {           
         while(fiveAmount<3) {
            try { System.out.println("\n"+Thread.currentThread().getName()+"靠边等...");
                  wait();       //如果使用该方法的线程传递的参数是20须等待
                  System.out.println("\n"+Thread.currentThread().getName()+"继续买票");
            }
            catch(InterruptedException e){}
         }
         fiveAmount=fiveAmount-3;
         twentyAmount=twentyAmount+1;
         System.out.println("给"+Thread.currentThread().getName()+"入场卷,"+
                            Thread.currentThread().getName()+"给20,找赎15元");
       }
       notifyAll();
   } 
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值