posts - 297,  comments - 1618,  trackbacks - 0
       这是以前为一师妹做的一机试题,虽后来因为她编程底子太弱,没能获得那份工作,拿在这里与大家共享之。
       题目如下:
      在生产者/消费者模型中,生产者Producer负责生产数据,而消费者Consumer负责使用数据。多个生产者线程会在同一时间运行,生产数据,并放到内存中一个共享的区域。期间,多个消费者线程读取内存共享区,消费里面的数据。
要求:
     1. 针对上面的场景,请创建2个类,一个叫Producer,一个叫Consumer. 
     2. Producer类继承Thread类,并实现把数据放到内存共享区的功能,这个功能要求是线程安全的。在个Producer类中的run方法中,循环20次,每次把一个整数放到内存共享区中。
     3. Consumer类也继承Thread类,并实现在没有冲突的情况下,从内存共享区中获取数据,并在标准输出设备中打印输出。输出的格式为:Consumer thread X retrieved integer Y.
     4. 最后,创建一个main class,创建10个Procuder线程和4个消费者线程并启动这些线程。
     5. 要求有效代码行数尽量少,最好不超过100行。
     我大概的做了一下,以下是我的代码实现:
     一. 消费者类
     
/**
 * 消费者类
 * 
@author Amigo Xie(xiexingxing1121@126.com)
 *
 
*/

class Consumer extends Thread 
    
private Conn conn; 
    
private int consumerNumber;
    
public Consumer(Conn conn1, int conNum) 
        conn 
= conn1;
        consumerNumber 
= conNum;
    }

    
    
public void run() 
        
for (int i = 0; i < 50; i++
            System.out.println(
"Consumer thread " +  consumerNumber + " retrieved integer: " + conn.read()); //
            try 
                sleep((
int) (Math.random() * 2000)); 
            }
 catch (InterruptedException e) {
                e.printStackTrace();
            }
 
        }
 
    }

}

    
      二. 生产者类
    
/**
 * 生产者类
 * 
@author Amigo Xie(xiexingxing1121@126.com)
 *
 
*/

class Producer extends Thread 
    
private Conn conn;

    
public Producer(Conn conn1) 
        conn 
= conn1;
    }

    
    
public void run() 
        
for (int i = 0; i < 20; i++
            conn.add(i);
        }
 
    }
 
}

     
       三. 线程通信类
/**
 * 线程通信类
 * 
@author Amigo Xie(xiexingxing1121@126.com)
 *
 
*/

class Conn 
    
private int buffer[] = new int[200]; //10个Procuder线程,需存放200个变量
    private int next = 0//Flags to keep track of our int buffer status 
    private boolean isFull = false
    
private boolean isEmpty = true

    
/**
     * method to read int
     * 
@return
     
*/

    
public synchronized int read() 
        
while (isEmpty == true//We can't read if there is nothing in our int buffer 
            try 
                wait();
//we'll exit this when isEmpty turns false
            }
catch (InterruptedException e) {
                e.printStackTrace();
            }
 
        }
 
        
        next
--//decrement the count,since we're going to read one int 
        if (next == 0
            isEmpty 
= true//Did we read the last letter? 
        }

        
        isFull 
= false;
        notify();
        
return (buffer[next]);//return the int to the thread that is reading 
    }


    
/**
     * method to add integer to the buffer
     * 
@param number
     
*/

    
public synchronized void add(int number) {  
        
while (isFull == true ) //Wait around until there's room to add another letter
            try 
                wait();
//This will exit when isFull turns false 
            }
catch (InterruptedException e) {
                e.printStackTrace();
            }
 
        }


        next
++//add the integer to the next available spot buffer[next]=number;Change the next available spot 
        if (next == 200
            isFull 
= true//Are we full?
        }
 else {
            buffer[next] 
= number; 
        }

        isEmpty 
=false
        notify(); 
    }
 
}


    四. 测试类
   
/**
 * 测试类
 * 
@author Amigo Xie(xiexingxing1121@126.com)
 *
 
*/

public class ProducerAndConsumerTest {

    
/**
     * 
@param args
     
*/

    
public static void main(String[] args) {
        Conn conn 
= new Conn();
        Producer pro1 
= new Producer(conn);
        Producer pro2 
= new Producer(conn);
        Producer pro3 
= new Producer(conn);
        Producer pro4 
= new Producer(conn);
        Producer pro5 
= new Producer(conn);
        Producer pro6 
= new Producer(conn);
        Producer pro7 
= new Producer(conn);
        Producer pro8 
= new Producer(conn);
        Producer pro9 
= new Producer(conn);
        Producer pro10 
= new Producer(conn);
        
        Consumer consumer1 
= new Consumer(conn, 1);
        Consumer consumer2 
= new Consumer(conn, 2);
        Consumer consumer3 
= new Consumer(conn, 3);
        Consumer consumer4 
= new Consumer(conn, 4);
        
        pro1.start();
        pro2.start();
        pro3.start();
        pro4.start();
        pro5.start();
        pro6.start();
        pro7.start();
        pro8.start();
        pro9.start();
        pro10.start();
        
        consumer1.start();
        consumer2.start();
        consumer3.start();
        consumer4.start();
    }


}


        近来发现,去看以前的代码,都觉得有点傻傻滴,现在的话如果去实现大抵会有所改进,我在进步中吗?啊哈。
posted on 2007-04-11 21:52 阿蜜果 阅读(6279) 评论(8)  编辑  收藏 所属分类: Java


FeedBack:
# re: 生产者/消费者模型模拟实现[未登录]
2007-04-11 23:01 | Tony
楼主的测试类可不怎么幽雅,呵呵  回复  更多评论
  
# re: 生产者/消费者模型模拟实现
2007-04-11 23:15 | 阿蜜果
@Tony
啊哈,是极其不优雅,以前写的代码哩
现在去看从前写的代码
有时真想对它动动刀子。。。  回复  更多评论
  
# re: 生产者/消费者模型模拟实现
2007-04-12 10:28 | 刘甘泉
哇,测试好多代码~~~~~~~  回复  更多评论
  
# re: 生产者/消费者模型模拟实现
2007-04-13 09:19 | riverbuilding
public synchronized void add
public synchronized int read
这两个方法造成的结果是生产者生产时消费者不能同时消费,这个逻辑不多。  回复  更多评论
  
# re: 生产者/消费者模型模拟实现
2007-04-13 13:53 | hs
楼上说的是,read方法的同步应该去掉。
另外发表一下个人意见,供大家参考指正:
以上的实现方法体现不出数据共享,或者说共享对象不明确。如果共享对象做成一个singleton,可能会好些,更能体现共享的含义。
新建 一个对象,然后通过传递该对象到不同的生产者或消费者以达到共享对象,这种做法欠妥。这种做法导致逻辑不清析,同时可能会产生过期引用对象,当你认为该对象已经无用的时候,可能该对象还被引用着,导致不能回收,你也很难跟宗和控制这个对象。把共享对象做成singleton,使共享的逻辑清析,也明确该对象永远存在。  回复  更多评论
  
# re: 生产者/消费者模型模拟实现[未登录]
2007-04-13 14:14 | 阿蜜果
@hs
@riverbuilding
:)
感谢你们的建议
这是以前写的一程序
打算抽空再重写一次。  回复  更多评论
  
# re: 生产者/消费者模型模拟实现
2007-04-13 16:59 | att
用 synchronizedList 代替你的那么通信类吧。  回复  更多评论
  
# re: 生产者/消费者模型模拟实现
2010-07-22 19:07 | Ilovesola
看了你的几篇文章,觉得还可以,所以多多关注了一下.

能写好生产-消费者的程序员不多.
代码我随便看了一下 和评论也看了一下
有人建议去 read同步方法, 这肯定不能去的,只能说明他们 对生产消费模弄理解不够深.

notify 建议换成 notifyAll();

最后,说明下,不知道你测试过没,你的程序貌似有个很严重的逻辑错误.

就是 应该首先add/read 对象,然后再next++ ,next--

我举个例子,
你执行 main方法 A线程 执行add方法 99次,然后B线程去read, 这时候 next=99,它就 read buffer[99] , 应该要read buffer[0]的
  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2007年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

      生活将我们磨圆,是为了让我们滚得更远——“圆”来如此。
      我的作品:
      玩转Axure RP  (2015年12月出版)
      

      Power Designer系统分析与建模实战  (2015年7月出版)
      
     Struts2+Hibernate3+Spring2   (2010年5月出版)
     

留言簿(262)

随笔分类

随笔档案

文章分类

相册

关注blog

积分与排名

  • 积分 - 2285132
  • 排名 - 3

最新评论

阅读排行榜

评论排行榜