java实现线程间的协作

    技术2024-08-20  67

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

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

    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()中。

    最新回复(0)