java 多线程-————等待唤醒机制

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();
		}
		
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值