下面代码存在的问题
- 循环的方法不对,每次需要消费者消费完消息或者生产者填满队列,其它线程才有执行的机会。
- wait的方法不对,如一个消费者c,两个生产者p1,p2当p1填满队列后,p1进入wait,假设p2继续执行,p2执行时发现队列已满也进行wait,消费者开始消费,消费完消息后,假设p1执行,填满队列后,p2被唤醒,这时p2从直接从wait出来,没有检查队列大小的代码,导致队列无限扩充。
import java.util.LinkedList;
class Test{
private LinkedList<Integer> llist;
private int maxSize = 5;
public Test() {
llist = new LinkedList<Integer>();
}
public void consume() {
synchronized(this) {
while(true) {
try {
Thread.sleep(1000);
}catch(Exception e) {
e.printStackTrace();
}
if(llist.size() == 0)
try {
System.out.println("consumer waiting for element " + llist.size());
wait();
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("consumer: " + llist.poll() + " " + llist.size());
notifyAll();
}
}
}
public void produce() {
synchronized(this) {
while(true) {
try {
Thread.sleep(1000);
}catch(Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + " before offer " + llist.size());
if(llist.size() == maxSize) {
try {
System.out.println(Thread.currentThread() + " wait" );
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
llist.offer(1);
System.out.println(Thread.currentThread() + " after offer " + llist.size());
notify();
}
}
}
}
public class consumer_producer {
public static void main(String[] args) {
Test t = new Test();
Thread t1 = new Thread() {
public void run() {
t.consume();
}
};
t1.start();
Thread t2 = new Thread() {
public void run() {
t.produce();
}
};
Thread t3 = new Thread() {
public void run() {
t.produce();
}
};
t2.start();
t3.start();
}
}
修改后
package com.zhang.learn.effective_java;
import java.util.LinkedList;
class Test{
private LinkedList<Integer> llist;
private int maxSize = 5;
public Test() {
llist = new LinkedList<Integer>();
}
public void consume() {
while(true) {
synchronized(this) {
while(llist.size() == 0) {
try {
System.out.println("consumer waiting for element " + llist.size());
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("consumer: " + llist.poll() + " " + llist.size());
notifyAll();
}
}
}
public void produce() {
while(true) {
try {
Thread.sleep(1000);
}catch(Exception e) {
e.printStackTrace();
} // 模拟获取与处理数据的时间
synchronized(this) {
while(llist.size() == maxSize) {
try {
System.out.println(Thread.currentThread() + " wait" );
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread() + " before offer " + llist.size());
llist.offer(1);
System.out.println(Thread.currentThread() + " after offer " + llist.size());
notify();
}
}
}
}
public class consumer_producer {
public static void main(String[] args) {
Test t = new Test();
Thread t1 = new Thread() {
public void run() {
t.consume();
}
};
t1.start();
Thread t2 = new Thread() {
public void run() {
t.produce();
}
};
Thread t3 = new Thread() {
public void run() {
t.produce();
}
};
t2.start();
t3.start();
}
}