java实现线程间的协作

在实际运用中,我们设置的多个线程往往要相互合作、通信,共同完成业务需求。

当任务协作时,关键是这些任务之间的同步、执行顺序问题。我们可以使用互斥来解决!

java语言中,可以通过基类Object的wait()、notify()、notifyAll()方法,协调线程交叉执行。

 

wait() : 在其它线程调用此对象的 notify()notifyAll() 方法前,导致当前线程等待。

notify() : 唤醒在此对象监视器上等待的单个线程。

因此所有任务必须等待相同的条件,以保证被唤醒的是恰当的那一个任务。

notifyAll() : 唤醒在此对象监视器上等待的所有线程,即只有等待这个锁的任务才会被唤醒。

因为这几个方法属于基类Object,它们操作的锁也是每个对象都有,故只能在同步控制方法或同步控制块中调用!

 

下面通过经典的生产者-消费者问题,来展示具体应用:

//生产者线程

public class Producer extends Thread{
 private Store store;
 public Producer(Store s){
  this.store = s;
 }
 public void run(){
  while(true){
   store.add();         //添加货物
   try{

    //在指定的毫秒数内让当前正在执行的线程休眠

    Thread.sleep(1000);      //调用sleep()的时候,锁并没有释放

}catch(InterruptedException e){
    e.printStackTrace();
   }
  }
 }
}

//消费者线程

public class Consumer extends Thread{
 private Store store;
 public Consumer(Store s){
  this.store = s;
 }
 public void run(){
  while(true){
   store.remove();        //取走货物
   try{
    Thread.sleep(1500);
   }catch(InterruptedException e){
    e.printStackTrace();
   }
  }
 }
}

//在每个生产者线程添加货物前,检查是否满仓;同理,取货之前也检查是否空仓

public class Store{
 private final int maxsize;        //仓库的最大容量
 private int count;               //仓库的当前容量
 public Store(int n){
    maxsize = n;
    count = 0;
 }
//进货
 public synchronized void add(){
  while(count >= maxsize){
   System.out.println("Store is full!");
   try{
    this.wait();                //如果满仓,就进入等待池  

    //wait()期间,对象锁是释放的!  所以在该对象中的其它synchronized方法可以在wait()期间被调用
   }catch(InterruptedException e){
    e.printStackTrace();
   }
  }
  count++;       //数量加1
  System.out.println(Thread.currentThread().toString() + " put " + count);
  this.notifyAll();     //通知所有的消费者线程来拿货 

}

//取货
 public synchronized void remove(){
  while(count <= 0){
   System.out.println("Store is empty!");
   try{
    this.wait();                //如果空仓,就进入等待池
   }catch(InterruptedException e){
    e.printStackTrace();
   }
  }
  count--;           //数量减1
  System.out.println(Thread.currentThread().toString() + " get " + count);
  this.notify();     //通知生产者添加货物
 }

 public static void main(String[] args){
  Store store = new Store(5);
  Thread pro = new Producer(store);
  Thread con = new Consumer(store);
  Thread pro2 = new Producer(store);
  Thread con2 = new Consumer(store);
  pro.setName("producer");
  con.setName("consumer");
  pro2.setName("producer2");
  con2.setName("consumer2");
  //启动线程
  pro.start();
  con.start();
  pro2.start();
  con2.start();
 }
}

 

在等待条件改变时使用wait()方法让线程休眠,还节约了CPU资源。当其它线程调用该对象的notify()、notifyAll()方法时,线程重新唤醒。

另外,把wait()置于一个检查关键条件的while循环中,可以保证在条件不满足时,返回到wait()中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值