好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

自己写的一个多线程的consumer 和 producter 模式

自己写的一个多线程的consumer 和 producter 模式

java的并发是一个复杂的主题,信手拈来就可以发现一大堆的有趣的问题。这里不讨论生产者模式,主要关注如何用java来实现该模式;

 package   ThreadTest;

  public   class   SetOfNum {
      private   int   numOne;//标记资源是否可用
      private   int   numTwo;//资源的内容
      public   int   getNumOne() {
          return   numOne;
    }
      public   void  setNumOne( int   numOne) {
          this .numOne =  numOne;
    }
      public   int   getNumTwo() {
          return   numTwo;
    }
      public   void  setNumTwo( int   numTwo) {
          this .numTwo =  numTwo;
    }
    
    SetOfNum(  int  a,  int   b){
        numOne  =  a;
        numTwo  =  b;
    }
    
} 

接着用一个resources类来作为缓冲区资源;

 package   ThreadTest;

  public   class   Resources {
      private   SetOfNum num;
      private   static   Resources res;
    
      private   Resources(SetOfNum num){
          this .num =  num;
    }
    
      public   SetOfNum getNum() {
          return   num;
    }

      public   void   setNum(SetOfNum num) {
          this .num =  num;
    }

      public   static   Resources getInstance(SetOfNum num){
          if (res ==  null  ){
            res  =  new   Resources(num);
        }
          else   res.setNum(num);
          return   res;
    }
    
      synchronized   public   int   getRes(){
          try  {
              if ( this .num.getNumOne() == -1 ){
                wait();
            }
        }  catch  (Exception e){
            e.printStackTrace();
        }
          this .getNum().setNumOne(-1 );
          return   this  .getNum().getNumTwo();
    }
    
      synchronized   public   void   setRes(){
          try  {
              if ( this .num.getNumOne() != -1 ){
                notifyAll();
                  return  ;
            }
        }  catch  (Exception e){
            e.printStackTrace();
        }
          this .num.setNumOne(1 );
          this .num.setNumTwo(( int )(Math.random()*1000 ));    
    }
} 

这里有三个有趣的问题:

1,为什么要对包含wait()和notify()的函数进行synchronized?

因为这里出现了典型的read and then change 的操作,那么在并发的时候就可能出现竞争条件,所以必须同步;

2,为什么作为线程的行为,wait()和notify()要放在object中而不是thread中呢?

这里wait(),notify()本质上是对资源加锁,而资源本身不是线程,而是某个object。这里我认为java库的开发者可能在实现的时候发现与其在对需要对某个资源进行加锁的操作(如果多次加锁,就要多次操作,很容易出错的),不如将操作直接写在资源上,也就是object上。

3,wait(),notify()和synchronized 之间有什么关系?

其实都没有什么关系,synchronized 本质是提供互斥锁(mutex)功能,而wait(),notify()是提供了线程间的通信;

接着是:

 package   ThreadTest;

  public   class  Producer  extends   Thread{
      private   Resources res;
      private   int  count = 20 ;
    Producer(Resources res){
          this .res =  res;
    }
      public   void   run(){
          while ( true  ){
              this  .res.setRes();
            count  -- ;
        }
    }
} 

 package   ThreadTest;

  public   class  Consumer  extends   Thread {
      private   Resources res;
      private   int   conId;
      private   int  count = 3 ;

    Consumer(Resources res,   int   conId) {
          this .res =  res;
          this .conId =  conId;
    }

      public   void   run() {
          while  (count > 0 ) {
              int  a =  res.getRes();
            System.out.println( "this is consumer " +  this .conId + "!" );
            System.out.println( "get the num is " + a + "!" );
            count  -- ;
        }
    }
} 

 package   ThreadTest;

  public   class   MainThread {
      public   static   void   main(String arg[]){
        SetOfNum num  =  new  SetOfNum(-1,1 );
        Resources res  = Resources.getInstance(num);
        Producer pro  =  new   Producer(res);
          //  pro.start(); 
        Consumer[] con =  new  Consumer[10 ];
          for ( int  i = 0; i < 10 ; i++ ){
            con[i]  =  new   Consumer(res,i);
            con[i].start();
        }
        pro.start();
        System.out.println( "in main thread!" );
    }
} 

这里的pro可以在不同地方试一下:(start是立即返回的)就会发现for循环的每一次迭代其实花费了很多时间,在main thread一次迭代的时间都可以被用来做多次的线程切换(输出从结果中得到)。

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于自己写的一个多线程的consumer 和 producter 模式的详细内容...

  阅读:39次