线程间通信——生产者和消费者模式

15 篇文章 0 订阅
13 篇文章 0 订阅

啦啦啦!我又来了!我是超carry的MF!

线程间通信

生产者和消费者问题
假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费。
如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止。
如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止。

在这里插入图片描述

Java提供了3个方法解决线程之间的通信问题
方法名作用
final void wait()表示线程一直在等待,直到其他线程通知
void wait(long timeout)线程等待指定毫秒参数的时间
fiial void wait (long timeout ,int nanos)线程等待指定毫秒,微妙的时间
final void notify()唤醒一个处于等待状态的线程
final void notifyAll()唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先运行
均是java.lang.Object类的方法都只能在同步方法或者同步代码块中使用,否则会抛出异常
package 消费者和生产者;
/*
 *厂库
 */
public class ShareData {
	private char c;
	private boolean isHaveShoping=false;//false代没有商品,true有商品了
	
	
	/**
	 * 存放商品
	 */
	public  synchronized void  save( char c  ){
		if(isHaveShoping){
				try {
					wait();//等待商品被取走,阻塞着
				} catch (InterruptedException e) {
					e.printStackTrace();}}
		System.out.println("进行存放商品");
		System.out.println("存放进来了"+c);
		this.c=c;
		System.out.println("存放结束");
		isHaveShoping=true;
		notify();//唤醒消费者
	}
	
	/**
	 * 取商品的
	 * @return
	 */
	public synchronized  char   get(){
		if(!isHaveShoping){
			try {
				wait();//等待被唤醒,生产者,有商品
				} catch (InterruptedException e) {e.printStackTrace();}}
		System.out.println("进行取商品");
		System.out.println("取走"+c);
		isHaveShoping=false;
		//唤醒生产,你继续生产
		notify();
		return  c;
	}	
}

定义生产者线程类和消费者线程类

package 消费者和生产者;
/**
 * 生产者
 * 
 * @author Administrator
 *
 */
public class Producer extends  Thread{
	ShareData  sd;
	
	public Producer(ShareData  sd) {
		this.sd=sd;
	}
		
	@Override
	public void run() {
		
		for(char c='a'; c<='f' ; c++){//生产
			
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			sd.save(c);//将商品存放在厂库中
		
		}	
	}

}

package 消费者和生产者;
/**
 * 消费者
 * 
 * @author Administrator
 *
 */

public class Consumer extends Thread{
	
	private ShareData  sd;
	
	
	public Consumer(ShareData  sd) {
		this.sd=sd;
	}
	
	
	@Override
	public void run() {
		
		for(int i=0;i<6;i++){
			
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			System.out.println("获取到了"+sd.get());				
		}
		
	}
	
}

定义一个测试

package 消费者和生产者;

public class Test02 {
	
	public static void main(String[] args) {
		
		ShareData  sd=new ShareData();
	
		new Producer(sd).start();		
		new Consumer(sd).start();
	}

}

运行结果
在这里插入图片描述

Sleep和wait的区别
这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。
最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法.
使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用.

今天到此结束,下周见了!老铁们!(看到朋友圈里的各位大佬深感自己是个小菜,希望自己能够和大佬们一样进入心仪的公司)!!!!!
我认为比较好的一片文章,解释多线程下-生产者和消费者之间的关系,有图比较容易理解,可以去看看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值