为线程打Call——通信之消费者生产者模型

为什么要线程通信

 

  • 多线程并发时,默认情况下CPU是随机切换线程的。当我们需要多个线程共同来完成一个任务,并且希望他们有规律的执行,那么线程之间就需要有一些协调的通信,以此来达到多个线程来操作一份数据。
  • 当然了,如果没有这种协调通信也是可以完成多线程操作同一份数据的,但是很有可能会出现线程对同一变量的争夺,这种情况就会出错。所以简而言之,线程通信就是为了避免多线程对同一共享变量的争夺

这是没有设置通信的多线程操作同一数据的结果

public class Manager {

	public static void main(String[] args) throws InterruptedException {
		
		Account ac = new Account(4000);
		GetCash gcATM = new GetCash(ac, "ATM取款", 2500);
		
		GetCash gcBANK = new GetCash(ac,"柜台取款", 2500);
		
		gcATM.start();
		gcBANK.start();
		Thread.sleep(5000);
		System.out.println(ac);
	}

}


public class GetCash extends Thread{

	private Account ac;
	private String flag;//取款方式
	private int disCount;//金额
	
	public GetCash(Account ac, String flag, int disCount) {
		super();
		this.ac = ac;
		this.flag = flag;
		this.disCount = disCount;
	}

	@Override
	public void run() {
		//取钱
		int cash = ac.getCash(disCount);
		System.out.println(flag+"取了:"+cash);
	}
}

public class Account {

	private  int total;
	
	//构造存有指定金额的银行账户
	public Account(int save) {
		this.total = save;
	}
	
	//从账户上提取现金的调用方法
	public int getCash(int count) {
		//金额不足
		if(total

为线程打Call——通信之消费者生产者模型_第1张图片 

解决办法:

使用同步锁synchronized锁住要对变量进行操作的方法或者代码块,比如此处的getCash()、disSave()方法 。这样就不会产生线程的争夺了。

为线程打Call——通信之消费者生产者模型_第2张图片

到底什么是线程通信呢?

 

  • 多个线程在处理同一个资源 ,并且任务不同时,需要线程通信来帮助进行同一变量的使用和操作,避免多个线程在操作同一变量时争夺。

 

如何实现线程通信?

 

  • synchronized锁

        上面的代码已经提到不再举例        

  • wait / notify 机制(消费者、生产者模型)

 

        实际上消费者、生产者模型也只是利用了wait()、notify()方法来控制对象锁的拥有权,并没有什么多余的知识······

 

public class Bank {

	private int product = 0;
	private int max_product = 10;
	private int min_product = 1;
	
	public synchronized void add() {
		if(product>=max_product) {
			try {
				wait();
				System.out.println("产品仓库放满了,停止生产中···");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return;
		}
		product ++;
		System.out.println("生产了第"+product+"个产品");
		notifyAll();
	}
	
	public synchronized void remove() {
		if(product

     

        至于消费产品和生产产品的优先顺序,就看线程自己抢占资源的能力了。但是由于存在wait / notify机制,并不会出现数据错误不符合事实的情况出现。

 

为线程打Call——通信之消费者生产者模型_第3张图片 

     

  若不使用wait()、notify()方法,可能会出现下面的情况

 

 为线程打Call——通信之消费者生产者模型_第4张图片

你可能感兴趣的:(java)