前提:生产者不断地生产产品,消费者取走生产者生产的产品。生产者生产出产品后将其放到一个区域之中,消费者从这个地方去除数据
分析: 1.是否设计多线程?是,生产者,消费者 2.是否涉及到共享数据?有!考虑线程的安全 3.此共享数据是谁?即为产品的数量 4.是否设计线程的通信?存在生产者与消费者的通信
public class Clerk {
//当前商品数量
private int product = 0;
public synchronized void addProduct() {//同步控制并发
while (product >= 5) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
product++;
System.out.println(Thread.currentThread().getName() + "生成了" + product + "产品");
notifyAll();//唤起所有阻塞的多线程
//notify 只能通知一个在等待的对象,其他在等待的对象不会通知,会导致多线程的并发问题
}
public synchronized void consumProduce() {
while (product <= 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "消费" + product + "产品");
product--;
notifyAll();
}
}
public class Consumer implements Runnable {//消费者
Clerk clerk;
public Consumer(Clerk clerk){
this.clerk = clerk;
}
@Override
public void run() {
System.out.println("消费者消费产品");
while (true){
clerk.consumProduce();
}
}
}
public class Product implements Runnable {//生产者
Clerk clerk;
public Product(Clerk clerk){
this.clerk = clerk;
}
@Override
public void run() {
System.out.println("生产者生产产品");
for(int i=0;i<10;i++){
clerk.addProduct();
}
}
}
多线程测试类:
public class TestProductConsume {
public static void main(String args[]){
Clerk clerk = new Clerk();
for(int i = 0; i < 4;i++){
Product p1 = new Product(clerk);
Consumer c1 = new Consumer(clerk);
Thread t1 = new Thread(p1);
Thread t2 = new Thread(c1);
t1.setName("生产者"+i);
t2.setName("消费者"+i);
t1.start();
t2.start();
}
}
}
notify只会通知一个在等待的对象,而notifyAll会通知所有在等待的对象,并且所有对象都会继续运行
被wait的线程,想要继续进行的话,必须满足2个条件:
1.经过有其他线程notify或notifyAll,并且当前线程被通知到
2.经过和其他线程进行锁竞争,成功获取锁