题目如下:
在生产者/消费者模型中,生产者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();
}