<span style="font-family: Arial, Helvetica, sans-serif;">当出现多个生产者、消费者时,为了保证生产一个,消费一个的原则,避免生产了多个,但消费了一个,其中一个丢失,或者出现生产一个,消费多次的情况,必须用while循环判断资源标志,以此保证多个生产者或消费者只能有一个工作,避免生产多个或者消费多次的情况。同时,为了避免只唤醒线程池中的本方线程,而没有唤醒对方的线程,而出现所有的线程都进入阻塞状态,造成程序执行不下去,我们应该调用notifyAll()方法唤醒所有的线程,让程序进行。
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">class Resource{</span>
private boolean flag=false;//Resource里是否有资源
public int count=0; //生产的编号
public synchronized void setInfo() {
while(flag)
try {
this.wait();//Resource对象作为锁旗标,wait()方法释放所占资源,同时释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(++count+"........in");
flag=true;
this.notifyAll();//唤醒阻塞的线程
}
public synchronized void getInfo(){
while(!flag)
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count+"..............out");
flag=false;
this.notifyAll();
}
}
class Produce implements Runnable{ //生产者
private Resource r;
public Produce(Resource r) {
this.r=r;
}
@Override
public void run() {
while(true){
r.setInfo();
}
}
}
class Conumser implements Runnable{ //消费者
private Resource r;
public Conumser(Resource r) {
this.r=r;
}
@Override
public void run() {
while(true){
r.getInfo();
}
}
}
public class InputOutputDemo2 {
public static void main(String[] args) {
Resource rs=new Resource();
Produce in=new Produce(rs);
Conumser out=new Conumser(rs);
new Thread(in).start(); //多个生产者、消费者
new Thread(out).start();
new Thread(in).start();
new Thread(out).start();
}
}
jdk1.5以上提供了线程升级解决方案。将同步synchronized替换成显式lock操作,将Object中的wait(),notify(),notifyAll()替换成Condition对象中的await(),signal(),signalAll(),该对象可以用lock锁进行获取。
修改后的例子如下:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Resource1{
private boolean flag=false;//Resource里是否有资源
private int count=0; //生产的编号
private Lock lock=new ReentrantLock();
private Condition con_pro=lock.newCondition(); //控制生产者
private Condition con_consum=lock.newCondition(); //控制消费者
public void setInfo() throws InterruptedException {
lock.lock();
try {
while(flag)
con_pro.await(); //让生产线程等待
System.out.println(++count+"........in");
flag=true;
con_consum.signal();//唤醒消费线程
} finally{
lock.unlock(); //finally里保证释放锁
}
}
public void getInfo() throws InterruptedException{
lock.lock();
try{
while(!flag)
con_consum.await(); //让消费线程等待
System.out.println(count+"..............out");
flag=false;
con_pro.signal(); //唤醒生产线程
}finally{
lock.unlock();
}
}
}
class Produce1 implements Runnable{ //生产者
private Resource1 r;
public Produce1(Resource1 r) {
this.r=r;
}
@Override
public void run() {
while(true){
try {
r.setInfo();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Conumser1 implements Runnable{ //消费者
private Resource1 r;
public Conumser1(Resource1 r) {
this.r=r;
}
@Override
public void run() {
while(true){
try {
r.getInfo();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class InputOutputDemo3 {
public static void main(String[] args) {
Resource1 rs=new Resource1();
Produce1 in=new Produce1(rs);
Conumser1 out=new Conumser1(rs);
new Thread(in).start(); //多个生产者、消费者
new Thread(out).start();
new Thread(in).start();
new Thread(out).start();
}
}