package thread线程;
//生产者消费者问题
//问题1:为什么要用while而不用if进行判断:因为是多线程在操作同一资源,即有多个生产者也有多个消费者,如果用if进行判断的话会出现生产者生产连续生产多次,而消费者只消费
//消费一次,或生产者生产一次消费者消费多次的错误信息,这是为什么呢?原因如下:
/*正常情况下:程序运行标记flag的初始值为false,当生产者t1去执行set方法时,如果是if语句它判断标记flag为false即让生产者生产,t1读到flag=true时将
* 标记置为true,然后读到notifyAll()的时候,会唤醒线程池中等待的其他线程t2、t3、t4,这个时候t1还具有cpu的执行权和执行资格,t1又重新执行sort方法
* 这个时候标记flag已经为true,当t1读到if语句的时候就会执行if语句中的内容wait(),t1被冻结释放出执行权和锁,这时候被唤醒的t2、t3、t4就会抢夺cpu执行权
* 如果生产者t2抢到了cpu执行权,那么它就会执行set()方法,当t2读到if语句的时候这时候标记flag=true,所以t2也会执行wait()方法进行等待,这个时候活着的
* 线程有t3和t4,它们两个就会抢夺cpu执行权。假如t3抢到了cpu执行权那么它就会执行out()方法,当读到if语句的时候这时候标记flag=true,它就会执行打印语句即
* 消费者进行消费,当t3读到flag=flase的时候就会将标记置为flase,读到notifyAll()的时候就会唤醒冻结中的t1和t2使他们从冻结状态转变为临时状态(拥有执行资格但是没有执行权)
* t1、t2、t3就会抢夺cpu执行权,如果t2抢到cpu的执行权(应该还记得t2已经读过了if判断语句,那么他就不会再去读if语句而是向下执行)生产者生产产品,读到flag=true
* 就会将标记flag设置为true,带到notifyAll()就会唤醒其它线程,这时候活着的线程有t1、t3、t4,如果t1抢到了cpu的执行权(还记得刚才t1也是读了if语句以后
* 才冻结的,它醒后和t2一样也会向下执行)这样生产者就又生产了一次产品,这样就出现了生产两次而消费一次,同理生产一次消费两次也是这个原因。
* 将
* */
public class 生产者消费者 {
public static void main(String[] args) {
Resource1 res=new Resource1();
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 Resource1{
private String name;
private int count;
private boolean flag;
Resource1(){
}
public synchronized void set(String name){
while(flag) try{this.wait();}catch(Exception e){e.printStackTrace();};
this.count=count+1;
this.name=name+"----"+this.count;
System.out.println(Thread.currentThread().getName()+"---生产者----"+this.name);
flag=true;
this.notifyAll();
}
public synchronized void out(){
while(!flag)try{wait();}catch(Exception e){e.printStackTrace();};
System.out.println(Thread.currentThread().getName()+"----消费者----"+name);
flag=false;
notifyAll();
}
}
class Producer implements Runnable{
Resource1 res;
Producer(Resource1 res){
this.res=res;
}
@Override
public void run() {
while(true){
res.set("商品");
}
}
}
class Consumer implements Runnable{
Resource1 res;
Consumer(Resource1 res){
this.res=res;
}
@Override
public void run() {
while(true){
res.out();
}
}
}
java 多线程-————等待唤醒机制
最新推荐文章于 2023-06-30 20:30:00 发布