生产者(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,而不是锁。