Java多线程㈣—①线程间通讯(生产者及消费者)

 在线程操作中有一个经典的案例程序,即生产者和消费者问题,生产者不断生产,消费者不断取走生产者生产的产品。

         假设:有两个线程,一个线程负责生产产品,一个线程负责消费产品。其中产品是两个线程处理的同一资源。由于线程的不确定性,所以会存在一下两点问题。

1、假设生产者线程向数据存储空间添加了资源的Husband,还没有加入该资源的Wife,程序就切换到了消费者线程,消费者线程将把资源的Husband和上一个信息的Wife联系到一起。

2、生产者放入了若干次的数据,消费者才开始取数据,或者是,消费者取完一个数据后,还没等到生产者放入新的数据,又重复取出已取过的数据。


程序的基本实现:

/*
线程间通讯:
多个线程在处理同一资源,但是任务却不同。
*/

//资源
class Resource{
	private String husband;
	private String wife;
	
	public void setHusband(String husband){
		this.husband = husband;
	}
	public String getHusband(){
		return husband;
	}
	
	public void setWife(String wife){
		this.wife = wife;
	}
	public String getWife(){
		return wife;
	}
}

//生产
class Producer implements Runnable{
	private boolean flag = true;
	private Resource r;
	public Producer (Resource r){
		this.r = r;
	}
	public void  run(){
		while(true){
			if(flag){
				r.setHusband("郭靖");
				r.setWife("黄蓉");		
				flag = false;	
			}else{
				r.setHusband("董永");
				r.setWife("七仙女");
				flag = true;
			}			
		}
	}
}

//消费
class Consumer implements Runnable{
	private Resource r;
	public Consumer (Resource r){
		this.r = r;
	}
	public void run(){
		while(true){
			System.out.println(r.getHusband()+"----------------"+r.getWife());
		}
	}
}

public class ThreadCommunication{
	public static void main(String[] args){
		//创建资源。
		Resource r = new Resource();
		//创建任务。
		Producer p = new Producer (r);
		Consumer c = new Consumer (r);
		//创建线程,执行路径。
		Thread t1 = new Thread(p);
		Thread t2 = new Thread(c);
		//开启线程
		t1.start();
		t2.start();
	}
}



问题解决一:加入同步代码块:

class Resource{
	private String husband;
	private String wife;
	
	public synchronized void set(String husband,String wife){
		this.husband = husband;
		this.wife = wife;
	}
	public synchronized Void get(){
		System.out.println(husband+"----------------"+wife);
	}
}

//生产
class Producer implements Runnable{
	private boolean flag = true;
	private Resource r;
	public Producer (Resource r){
		this.r = r;
	}
	public void  run(){
		while(true){
			if(flag){
				r.set("郭靖","黄蓉");
				flag = false;	
			}else{
				r.set("董永","七仙女");
				flag = true;
			}			
		}
	}
}

//消费
class Consumer implements Runnable{
	private Resource r;
	public Consumer (Resource r){
		this.r = r;
	}
	public void run(){
		while(true){
			r.get();
		}
	}
}

public class ThreadCommunication2{
	public static void main(String[] args){
		//创建资源。
		Resource r = new Resource();
		//创建任务。
		Producer p = new Producer (r);
		Consumer c = new Consumer (r);
		//创建线程,执行路径。
		Thread t1 = new Thread(p);
		Thread t2 = new Thread(c);
		//开启线程
		t1.start();
		t2.start();
	}
}



从程序的运行结果中可以发现,信息错乱的问题已经解决了,但是依然存在重复读取的问题,既然有重复读取,则肯定会有重复设置的问题,那么对于这样的问题该如何解决呢?

此时,就需要使用 Object类中的方法了(wait、notify、notifyAll)




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值