生产者和消费者
程序员文章站
2022-07-12 17:41:07
...
生产者和消费者
多线程的经典模型
两个角色:生产者和消费者
线程公共变量(判断条件)
第一种方式
用synchronized
class AirCondition{
private int number =0;
public AirCondition() {}
public int getNumber() {return number;}
public AirCondition(int number) {this.number = number;}
public synchronized void increment()throws Exception{
//第一步判断
while (number!=0) {
this.wait();
}
//第二步干活
number++;
System.out.println(Thread.currentThread().getName()+"生产了一个"+number); //第三步通知
this.notifyAll();
}
public synchronized void decrement()throws Exception{
while (number==0){
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"消费了一个"+number);
this.notifyAll();
}
}
在只有两个线程的时候,不是生产者就是消费者。
notifyAll();若生产者唤起所有线程,当前线程并没有wait();,唤起的就是唯一的另一个线程消费者。
当多个线程的时候,如生产者唤起所有线程,唤起的不只有消费者线程,可能还有另一个生产者线程。
在最初学习时习惯写if()判断,被唤起的生产者线程可能已经通过了if()判断,而此时公共变量已经被改变了,被唤起的生产者线程在此基础上的操作很有可能就出错了。
可以学习jdk文档里找wait()介绍,可知应用while循环判断,如此当线程被唤起时还会被判断一次。
第二种方式
用lock方法
class AirCondition{
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public AirCondition() {number=0;}
public int getNumber() { return number;}
public AirCondition(int number) { this.number = number; }
public void increment()throws Exception{
//第一步判断
lock.lock();
try {
while (number!=0) {
condition.await();//相当于wait
}
//第二步干活
number++;
System.out.println(Thread.currentThread().getName()+"生产了一个"+number);
condition.signalAll();//相当于notifyAll();
}finally {
//第三步通知
lock.unlock();
}
}
public synchronized void decrement()throws Exception{
lock.lock();
try {
while (number==0){
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName()+"消费了一个"+number);
condition.signalAll();
}finally {
lock.unlock();
}
}
}
synchronized 和lock不能混用,wait功能由Condition的await方法实现,notrifyAll由signalAll方法实现。
下一篇: 大型网站技术架构读书笔记