欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

生产者和消费者

程序员文章站 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方法实现。

相关标签: java