程序说明:2个生产者,2个消费者, 生产一个商品,消费一个商品(商品有标号)
特殊:这里生产者、消费者都有多个,
1. 如果生产者、消费者都是1个,那么flag标记可以用if判断。这里有多个,必须用while判断.
2. 在while判断的同时,notify函数可能唤醒本类线程(如一个消费者唤醒另一个消费者),这会导致所有消费者忙等待,程序无法继续往下执行。
使用notifyAll函数代替notify可以解决这个问题, notifyAll可以保证非本类线程被唤醒(消费者线程能唤醒生产者线程,反之也可以),解决了忙等待问题
package test;
class Person {
}
/*
程序说明:2个生产者,2个消费者, 生产一个商品,消费一个商品(商品有标号)
特殊:这里生产者、消费者都有多个,
1. 如果生产者、消费者都是1个,那么flag标记可以用if判断。这里有多个,必须用while判断.
2. 在while判断的同时,notify函数可能唤醒本类线程(如一个消费者唤醒另一个消费者),这会导致所有消费者忙等待,程序无法继续往下执行。
使用notifyAll函数代替notify可以解决这个问题, notifyAll可以保证非本类线程被唤醒(消费者线程能唤醒生产者线程,反之也可以),解决了忙等待问题
*/
class Resource {
private String name = "";
private int count = 1;
private boolean flag = false;
public synchronized void produce(String name) {
while (flag) //注意判断标记用while,每次线程唤醒都要先判断标记
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.name = name +"--"+ count++;
System.out.println(Thread.currentThread().getName()+": 生产者....."+this.name);
flag = true;
this.notifyAll(); //notifyAll()代替notify(),解决忙等待问题
}
public synchronized void consume() {
while(!flag) //注意判断标记用while,每次线程唤醒都要先判断标记
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+": 消费者.........."+this.name);
flag = false;
this.notifyAll(); //notifyAll()代替notify(),解决忙等待问题
}
}
class Producer implements Runnable {
private Resource res;
Producer(Resource res) {
this.res = res;
}
public void run() {
while (true) {
res.produce("商品");
}
}
}
class Consumer implements Runnable {
private Resource res;
Consumer(Resource res) {
this.res = res;
}
public void run() {
while (true) {
res.consume();
}
}
}
public class Test {
public static void main(String[] args) {
Resource res = new Resource();
Producer producer = new Producer(res);
Consumer consumer = new Consumer(res);
Thread t1 = new Thread(producer);
Thread t2 = new Thread(producer);
Thread t3 = new Thread(consumer);
Thread t4 = new Thread(consumer);
t1.start();
t2.start();
t3.start();
t4.start();
}
}