生产消费者模型


一、生产者消费者模型是什么?

其实生产者消费者模型就是线程之间的通信,因为听名字就知道这个模型肯定有两个人,一个是生产者,一个是消费者,生产者一边生产,消费者一边消费。这两个线程同时进行,并且是对同一个物体进行操作,所以涉及到这两个线程的通信。

二、代码

  • 以一个例子来写代码,比如一个家里有一个母亲往家里挣钱,然后儿子和女儿花家里的钱,母亲边挣,两个败家孩子边花。
  • 代码如下
public class MyConusm {
	public static void main(String[] args) {
		Home home = new Home();
		
		Mother mother = new Mother(home);
		Son son = new Son(home);
		Daughter daughter = new Daughter(home);
		
		mother.start();
		
		son.setName("儿子");
		daughter.setName("女儿");
		
		son.start();
		daughter.start();
	}
}

//家是共享数据,也是锁,就要等妈妈挣完钱,儿子女儿才能花,
class Home{
	private int money = 0;
	//这里要加锁的原因是当money++的时候,儿子可能就花了,明明挣钱之后money是10,但打印出来可能是9.
	public synchronized void MakeMoney() {
		if( money < 20 ) {
			money++;
			System.out.println("妈妈开始挣钱" + money);
			//notifyAll()的意思是只要妈妈挣了一块钱,就释放其他两个线程,儿子女儿就可以花了
			notifyAll();
		}else {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	//这里同理
	public synchronized void LayOut() {
		if( money > 0 ) {
			money--;
			System.out.println(Thread.currentThread().getName() + "开始花钱 " + money);
			try {
				Thread.sleep(30);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			notifyAll();
		}else {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

class Mother extends Thread{
	
	Home home;
	
	public Mother(Home home) {
		this.home = home;
	}
	
	public void run() {
		while(true) {
			home.MakeMoney();
		}
	}
}

class Son extends Thread{
	
	Home home;
	
	public Son(Home home) {
		this.home = home;
	}
	
	public void run() {
		while(true) {
			home.LayOut();
		}
	}
}

class Daughter extends Thread{
	
	Home home ;
	
	public Daughter(Home home) {
		this.home = home;
	}
	
	public void run() {
		while(true) {
			home.LayOut();;
		}
	}
}

三、常见面试题

说说 sleep() 方法和 wait() 方法区别和共同点

区别:

  1. sleep()只是休眠 ,wait()则是释放锁,只有释放了锁,其他线程才能进来
  2. sleep()执行完里面的时间之后会自动释放锁,wait() 需要notify() 和notifyAll()
  3. sleep() 主要用于线程的暂停,wait() 用于线程的通信

相同点:两者都可以暂停线程的执行。

为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法

这涉及到线程的生命周期:

  1. 首先,我们通过new 来创建一个线程,
  2. 然后这个线程去cpu哪里排队,等cpu给他时间片(start())
  3. 然后执行run()方法
  4. 执行完run()方法之后(或者调用stop())线程结束,当然这里可能会有线程的阻塞什么的,就比如sleep(),wait(),但这些在这个问题里不是重点
  5. 以上才是线程的执行过程
  6. 要是直接调用run()方法,他就只是调用了run()方法,是按顺序执行的,达不到主程序和线程里的程序同时执行的效果。

一个线程两次调用start()方法会出现什么情况

Java的线程是不允许启动两次的,第二次调用必然会抛出IllegalThreadStateException,这是一种运行时异常,多次调用start被认为是编程错误。

在上个题里面简单说了下线程的生命周期,当一个线程启动时,它可能处于不同的等待状态,再次start()是必然会报错的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值