生产者和消费者问题是多线程通信的经典问题。这类问题描述了这样一种情况:假设有一个仓库,用来存储产品,有生产者负责生产产品,有消费者负责消费。生产者生产的产品存放在仓库之中,消费者从仓库之中取出产品。显然这是一个同步问题,生产者和消费者共享同一资源,并且生产者和消费者之间彼此依赖,互为条件向前推进。那么,该如何编写代码来实现呢?
class Resource {
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name, String sex) {
if (flag == true) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name + "--" + sex;
System.out.println(Thread.currentThread().getName() + "--生产者--"
+ this.name);
flag = true;
notify();
}
public synchronized void out() {
if (flag == false) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "---消费者---"
+ this.name);
flag = false;
notify();
}
}
class Producer implements Runnable {
private Resource resource;
private int num = 0;
Producer(Resource resource) {
this.resource = resource;
}
public void run() {
while (true) {
if (num == 1) {
resource.set("丽丽", "女女女");
} else {
resource.set("mike", "man");
}
num = ++num % 2;
}
}
}
class Consumer implements Runnable {
private Resource resource;
Consumer(Resource resource) {
this.resource = resource;
}
public void run() {
while (true) {
resource.out();
}
}
}
class Communicate {
public static void main(String[] args) {
Resource resource = new Resource();
Producer pro = new Producer(resource);
Consumer con = new Consumer(resource);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
t1.start();
t2.start();
}
}但是还有一个问题,这个例子只是一个线程用来生产,一个线程用来消费,那如果多加几个线程呢?
那我们多加上几个线程试试。
class Resource {
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name, String sex) {
if (flag == true) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name + "--" + sex;
System.out.println(Thread.currentThread().getName() + "--生产者--"
+ this.name);
flag = true;
notify();
}
public synchronized void out() {
if (flag == false) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "---消费者---"
+ this.name);
flag = false;
notify();
}
}
class Producer implements Runnable {
private Resource resource;
private int num = 0;
Producer(Resource resource) {
this.resource = resource;
}
public void run() {
while (true) {
if (num == 1) {
resource.set("丽丽", "女女女");
} else {
resource.set("mike", "man");
}
num = ++num % 2;
}
}
}
class Consumer implements Runnable {
private Resource resource;
Consumer(Resource resource) {
this.resource = resource;
}
public void run() {
while (true) {
resource.out();
}
}
}
class Communicate {
public static void main(String[] args) {
Resource resource = new Resource();
Producer pro = new Producer(resource);
Consumer con = new Consumer(resource);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}在打印结果中我们发现会有这种情况:
Thread-1--生产者--mike--man
Thread-0--生产者--mike--man
Thread-2---消费者---mike--man
还可能会发生生产一个而消费两个的情况。出现的原因在 wait()这,就不过多的解释了。
只需要将判断flag 的if 改为while 同时将notify改为notifyAll() 就ok。
修改完如下:
class Resource {
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name, String sex) {
while (flag == true) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name + "--" + sex;
System.out.println(Thread.currentThread().getName() + "--生产者--"
+ this.name);
flag = true;
notifyAll();
}
public synchronized void out() {
while (flag == false) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "---消费者---"
+ this.name);
flag = false;
notifyAll();
}
}
class Producer implements Runnable {
private Resource resource;
private int num = 0;
Producer(Resource resource) {
this.resource = resource;
}
public void run() {
while (true) {
if (num == 1) {
resource.set("丽丽", "女女女");
} else {
resource.set("mike", "man");
}
num = ++num % 2;
}
}
}
class Consumer implements Runnable {
private Resource resource;
Consumer(Resource resource) {
this.resource = resource;
}
public void run() {
while (true) {
resource.out();
}
}
}
class Communicate {
public static void main(String[] args) {
Resource resource = new Resource();
Producer pro = new Producer(resource);
Consumer con = new Consumer(resource);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
原文:http://blog.csdn.net/u013476556/article/details/42875267