zoukankan      html  css  js  c++  java
  • 经典问题-生产者和消费者问题

    生产者和消费者是一个多线程同步的经典案例,该问题描述了两个共享固定大小缓冲区的线程,即所谓的“生产者”和“消费者”,顾名思义,生产者指的就是生产一定的数据量到缓冲区,而消费者就是从缓冲区取走一定的数据。

    生产者和消费者问题要解决一个死锁问题,就是当缓冲区已经满的时候,生产者占着它等待消费者来取走数据,而消费者则等着生产者让出缓冲区的权利好取走数据,于是就相互等待,从而造成死锁。

    本程序只有一个生产者和一个消费者,使用wait和notify(nitify)方法来避免死锁问题,这里得提一下wait和notify(notifyAll)方法,线程中的wait、notify以及notifyAll方法:都是定义在Object类中的final方法,即所有的类都默认拥有这3个方法,但只用于synchronized关键字作用的范围内,并且是搭配着一起使用;wait方法是通知当前线程等待并释放对象锁;notify方法是通知等待此对象锁的一个线程重新获得线程锁;notifyAll是唤醒所有等待此对象锁的线程。

    public class ProducerConsumer {
    	
    	public static void main(String[] args) {
    		
    		SyncStack myStack = new SyncStack(6);
    		
    		Producer producer = new Producer(myStack);
    		Consumer consumer = new Consumer(myStack);
    		
    		Thread t1 = new Thread(producer);
    		Thread t2 = new Thread(consumer);
    		
    		t1.start();
    		t2.start();
    		
    	}
    }
    
    class Bread {
    	
    	private int id;
    	
    	Bread(int id) {
    		this.id = id;
    	}
    	
    	public int getId() {
    		return id;
    	}
    }
    
    
    class SyncStack {
    	
    	private int size;
    	private int index = 0;
    	private Bread[] myBread;
    	
    	SyncStack(int size) {
    		this.size = size;
    		myBread = new Bread[size];
    	}
    	
    	public synchronized void put(Bread bread) {
    		while (index == size) {
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		myBread[index] = bread;
    		++index;
    		System.out.println("Producer puts bread: " + bread.getId());
    		this.notify();
    	}
    	
    	public synchronized Bread remove() {
    		while (index == 0) {
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		--index;
    		System.out.println("Consumer removers bread: " + myBread[index].getId());
    		this.notify();
    		return myBread[index];
    	}	
    	
    }
    
    class Producer extends Thread {
    	
    	private SyncStack myStack;
    	
    	Producer(SyncStack myStack) {
    		this.myStack = myStack;
    	}
    	
    	public void run() {
    		
    		for (int i = 1; i <= 20; ++i) {
    			myStack.put(new Bread(i));
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    
    class Consumer extends Thread {
    	
    	private SyncStack myStack;
    	
    	Consumer(SyncStack myStack) {
    		this.myStack = myStack;
    	}
    	
    	public void run() {	
    		for (int i = 1; i <= 20; ++i) {	
    			Bread bread = myStack.remove();
    			try {
    				Thread.sleep(2000);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    }


  • 相关阅读:
    四则运算出题器
    四则运算出题网页
    四则运算自动生成器实现(python、wxpython、GUI)
    python 实现小学四则运算
    Process and Thread States
    COS AP-开启WPA后无法关联SSID!
    WLC MAC Filtering
    禅道--个人理解 简单介绍
    IDEA解决乱码
    avue 实现自定义列显隐并保存,并且搜索表单、form表单、crud列顺序互不影响。
  • 原文地址:https://www.cnblogs.com/wally/p/4477038.html
Copyright © 2011-2022 走看看