Java多线程经典例题一

生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。

public class TestProduct {
	public static void main(String[] args) {
		Clerk01 clerk01 = new Clerk01();
		Thread pro = new Thread(new Productor01(clerk01));
		Thread con = new Thread(new Consumer01(clerk01));
		pro.start();
		con.start();
		
		
	}
}

//销售员
class Clerk01 {
	private int product = 0;
	
	
	
	//生产商品
	public synchronized void add() {
		if (product >= 20) {
			try {
				wait();
				System.out.println("请暂停生产!");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}else{
			product++;
			System.out.println("生产者生产了第"+product+"个商品!");
			notifyAll();
			
		}
	}
	
	//消费商品
	public synchronized void remove(){
		if (this.product <= 0) {
			try {
				
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}else{
			System.out.println("顾客取走了第"+ product +"个商品");
			product--;
			notifyAll();
		}
	}
	
	
}


//生产者
class Productor01 implements Runnable {
	Clerk01 clerk01;
	
	public Productor01(Clerk01 clerk01){
		this.clerk01 = clerk01;
	}
	@Override
	public void run() {
//		System.out.println("货架空了!");
		System.out.println("现在开始生产产品");
		while(true){
			try {
				Thread.sleep((int)(Math.random()*2000));
			} catch (InterruptedException e) {
				
			}
			clerk01.add();
		}
		
	}   
	
}

//消费者
class Consumer01 implements Runnable {
	Clerk01 clerk01;
	
	public Consumer01(Clerk01 clerk01){
		this.clerk01 = clerk01;		
	}
	
	@Override
	public void run() {
		System.out.println("消费者开始取产品");
		while(true){
			try {
				Thread.sleep((int)(Math.random()*2000));
			} catch (InterruptedException e) {
				
			}
			clerk01.remove();
		}
	}
	
}

synchronized关键字

synchronized关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、D等)正在用这个方法,若有则要等正在使用synchronized方法的线程B(或者C、D)运行完这个方法后再运行此线程A,若没有则直接运行。

wait() 方法是等待的意思,在lang包中,所以不需要导包等可以直接调用。它与 notify() 和 notifyAll() 这两个方法往往同时存在,这两个方法用来唤醒wait()的等待,其中这两种唤醒方法的区别大家应该都知道,末尾的All 就说明了一切。接下来我们进行详细的区别解释。

notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。

void notify(): 唤醒一个正在等待该对象的线程。
void notifyAll(): 唤醒所有正在等待该对象的线程。
两者的最大区别在于:
notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,
他们就会去竞争。

notify他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对

象notify的线程们,当第一个线程运行完毕以后释放对象上的锁,此时如果该对象没有再次使用notify语句

即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这

个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。


你可能感兴趣的:(Java)