第一种:使用wait()和notify()方法解决生产者和消费者问题:
关键步骤:
①要对入队和出队方法都加上“锁”,保证任意时刻只有一个线程访问资源;
②并且当队列已满或已空时,要调用wait()方法,让当前线程等待,直到被唤醒notify();
③在生产者和消费者线程中,可以在每一次入队和出队操作之后调用sleep()方法,让当前线程暂停释放CPU时间让另一线程执行,以实现入队出队依次交叉进行。
class synqueue { //这是我们自己写的一个阻塞队列
private int front = 0, rear = 0;
final static int maxSize = 6;
private char[] b = new char[maxSize]; //用数组模拟生产者与消费者共享资源区
synchronized void enqueue(char c) { //入队操作
if ((rear + 1)%maxSize==front) { //队列已满
try {
this.wait(); //暂停执行入队的线程,进入队列的wait池。
} catch (InterruptedException e) {
}
}
this.notify(); //唤醒在此对象监视器上等待的单个线程
rear = (rear + 1) % maxSize; //得到队尾的位置
b[rear] = c; //向队尾插入字符
}
synchronized char outquqeue() { //出队操作
if (front == rear) { //队列已空
try {
this.wait();
} catch (InterruptedException e) {
}
}
this.notify();
front = (front + 1) % maxSize; //队首向下移一个
return b[front]; //返回原队首的元素
}
}
class producer implements Runnable { //生产者线程
synqueue sq;
producer(synqueue sq1) {
sq = sq1;
}
public void run() {
char c;
for (int i = 0; i < 10; i++) {
c = (char) (Math.random() * 26 + 'A');
sq.enqueue(c);
System.out.println("producer=" + c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
class customer implements Runnable { //消费者线程
synqueue sq;
customer(synqueue sq1) {
sq = sq1;
}
public void run() {
char c;
for (int i = 0; i < 10; i++) {
c = sq.outquqeue();
System.out.println("customer=" + c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public class ProducerConsumerPattern {
public static void main(String[] args) {
synqueue sq = new synqueue();
producer pro = new producer(sq);
customer cus = new customer(sq);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(cus);
t1.start();
t2.start();
}
}
第二种:使用阻塞队列解决生产者与消费者问题:
主要是使用java提供的BlockingQueue类的put()和take()方法。
public class ProducerConsumerPattern {
public static void main(String args[]) {
// 创建共享的阻塞队列
BlockingQueue sharedQueue = new LinkedBlockingQueue();
//创建生产者与消费者线程
Thread prodThread = new Thread(new Producer(sharedQueue));
Thread consThread = new Thread(new Consumer(sharedQueue));
// 启动生产者与消费者线程
prodThread.start();
consThread.start();
}
}
// 生产者线程
class Producer implements Runnable {
private final BlockingQueue sharedQueue;
public Producer(BlockingQueue sharedQueue) {
this.sharedQueue = sharedQueue;
}
public void run() {
for (int i = 0; i < 10; i++) {
try {
System.out.println("Produced: " + i);
sharedQueue.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 消费者线程
class Consumer implements Runnable {
private final BlockingQueue sharedQueue;
public Consumer(BlockingQueue sharedQueue) {
this.sharedQueue = sharedQueue;
}
public void run() {
while (true) {
try {
System.out.println("Consumed: " + sharedQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}