學習下生產者消費者模式下,線程同步的問題。當然對這些問題,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();
}
}
}
}