对于多个生产者和消费者:
1.不要用if ,而要定义while判断标记,使得被唤醒的线程再一次判断标记;
2.需要使用notifyAll唤醒对方线程。因为之用notify,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待。
但使用notifyAll不仅仅会唤醒对方线程,也会唤醒本方线程,这种解决方案并不是很好。
package com.javase.thread;
public class ProducerConsumer {
public static void main(String[] args){
Resources res = new Resources();
Thread t1 = new Thread(new Producer(res));
Thread t2 = new Thread(new Producer(res));
Thread t3 = new Thread(new Consumer(res));
Thread t4 = new Thread(new Consumer(res));
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resources{
private String name;
private int count=0;
boolean flag = false;
public synchronized void set(String name){
while(flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name;
System.out.println("***生产者:"+name+(++count));
flag=true;
notifyAll();
}
public synchronized void print(){
while(!flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者:"+this.name+count);
flag=false;
notifyAll();
}
}
class Producer implements Runnable{
private Resources res ;
public Producer(Resources res){
this.res=res;
}
public void run(){
while(true)
res.set("Product");
}
}
class Consumer implements Runnable{
private Resources res ;
public Consumer(Resources res){
this.res=res;
}
public void run(){
while(true)
res.print();
}
}
JDK1.5 中提供了多线程升级解决方案。将同步Synchronized替换成现实Lock操作。将Object中的wait,notify , notifyAll 替换成Condition对象。该对象可以通过Lock锁进行获取。下面代码实现了本方只唤醒对方的操作。
package com.javase.thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProducerConsumer {
public static void main(String[] args){
Resources res = new Resources();
Thread t1 = new Thread(new Producer(res));
Thread t2 = new Thread(new Producer(res));
Thread t3 = new Thread(new Consumer(res));
Thread t4 = new Thread(new Consumer(res));
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resources{
private Lock resLock = new ReentrantLock();
private Condition condition_pro = resLock.newCondition();
private Condition condition_con = resLock.newCondition();
private String name;
private int count=0;
boolean flag = false;
public void set(String name){
resLock.lock();
try{
while(flag){
try {
condition_pro.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name;
System.out.println(Thread.currentThread().getName()+"--生产者:"+name+(++count));
flag=true;
condition_con.signal();
}finally{
resLock.unlock();
}
}
public void print(){
resLock.lock();
try{
while(!flag){
try {
condition_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"--消费者:"+this.name+count);
flag=false;
condition_pro.signal();
}finally{
resLock.unlock();
}
}
}
class Producer implements Runnable{
private Resources res ;
public Producer(Resources res){
this.res=res;
}
public void run(){
while(true)
res.set("Product");
}
}
class Consumer implements Runnable{
private Resources res ;
public Consumer(Resources res){
this.res=res;
}
public void run(){
while(true)
res.print();
}
}