学习下生产者消费者模式下,线程同步的问题。当然对这些问题,Java已经在concurrent包下已经做了处理,以下代码仅仅为了学习下多线程wait和notify。
import java.util.concurrent.ArrayBlockingQueue;
public class ProducerAndConsumer {
public static void main(String[] args) {
System.out.println("program start");
MessageQueue<Object> queue = new MessageQueue<Object>(10000);
Thread prodThread = new ProducerThread(queue);
Thread consThread = new ConsumerThread(queue, prodThread);
prodThread.start();
consThread.start();
if (consThread.isAlive() && prodThread.isAlive()) {
System.out.println("all thread has started and running.");
}
}
}
class MessageQueue<T> extends ArrayBlockingQueue<T> {
private int capacity;
public MessageQueue(int capacity) {
// TODO Auto-generated constructor stub
super(capacity);
this.capacity = capacity;
}
/**
*
*/
private static final long serialVersionUID = -8900156905307830983L;
@Override
public void put(T e) throws InterruptedException {
// TODO Auto-generated method stub
if (size() < capacity) {
super.put(e);
return;
}
synchronized (this) {
if (size() > capacity) {
wait();
super.put(e);
return;
}
}
super.put(e);
}
@Override
public T remove() {
// TODO Auto-generated method stub
if (size() < capacity && size() > 0) {
return super.remove();
}
T t = null;
while (size() > 0) {
synchronized (this) {
t = super.remove();
notify();
}
}
return t;
}
}
class ConsumerThread extends Thread {
MessageQueue<Object> queue;
Thread producerThread;
public ConsumerThread(MessageQueue<Object> queue, Thread producerThread) {
// TODO Auto-generated constructor stub
this.queue = queue;
this.producerThread = producerThread;
}
@Override
public void run() {
// TODO Auto-generated method stub
while (producerThread.isAlive()) {
if (queue.size() > 0) {
Object obj = queue.remove();
System.out.println("consum: " + obj.toString() + " size: " + queue.size());
}
}
}
}
class ProducerThread extends Thread {
MessageQueue<Object> queue;
public ProducerThread(MessageQueue<Object> queue) {
// TODO Auto-generated constructor stub
this.queue = queue;
}
@SuppressWarnings("deprecation")
@Override
public void run() {
// TODO Auto-generated method stub
int i = 0;
while (true) {
try {
queue.put(i++);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Thread.currentThread().stop();
}
}
}
}