生产者 / 消费者 面试题

题目:
两个线程,可以操作初始值为0的变量。实现一个线程对该变量加1,一个线程对该变量减一实现交替,来10轮,变量初始值为0

class AirConditioner{
    private int number=0;
    
    synchronized public void increase() throws InterruptedException {
        if(number != 0){
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName() +"\t"+ number);
        this.notifyAll();
    }

    synchronized public void decrease() throws InterruptedException {
        if(number == 0){
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName() +"\t"+ number);
        this.notifyAll();
    }
}

public class ThreadWaitNotifyDemo {
    public static void main(String[] args) {
        AirConditioner airConditioner = new AirConditioner();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airConditioner.increase();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        
        new Thread(() -> {

            for (int i = 0; i <10 ; i++) {
                try {
                    airConditioner.decrease();
                }catch (InterruptedException e ){
                    e.printStackTrace();
                }
            }
           
        },"B").start();
    }
}

此时运行结果正确。

当线程的数量增加为4个时,两个实现加一,两个实现减一。

public class ThreadWaitNotifyDemo {
    public static void main(String[] args) {
        AirConditioner airConditioner = new AirConditioner();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airConditioner.increase();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        
        new Thread(() -> {

            for (int i = 0; i <10 ; i++) {
                try {
                    airConditioner.decrease();
                }catch (InterruptedException e ){
                    e.printStackTrace();
                }
            }
           
        },"B").start();
        new Thread(() -> {

            for (int i = 0; i <10 ; i++) {
                try {
                    airConditioner.increase();
                }catch (InterruptedException e ){
                    e.printStackTrace();
                }
            }

        },"C").start();
        new Thread(() -> {

            for (int i = 0; i <10 ; i++) {
                try {
                    airConditioner.decrease();
                }catch (InterruptedException e ){
                    e.printStackTrace();
                }
            }

        },"D").start();

    }
}

此时结果就不正确了。
生产者 / 消费者 面试题
这是因为不能使用if要是用where
生产者 / 消费者 面试题更改以后的代码

synchronized public void decrease() throws InterruptedException {
        while( number != 0){
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName() +"\t"+ number);
        this.notifyAll();
    }
    
    synchronized public void increase() throws InterruptedException {
        while(number == 0){
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName() +"\t"+ number);
        this.notifyAll();
    }

这样就不会出现上面的问题了。

第二种方法:采用JUC的方法。
java.util.concurrent.locks
Lock是一个接口。

Interface Lock

有以下实现类: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock。其中我们需要用到ReentrantLock

class AirConditioner03 {
    private int number = 0;
    Lock lock = new ReentrantLock();
    Condition condition =lock.newCondition();

    public void decrease() {
       
        try {
            lock.lock();
            while (number != 0){
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"\t"+ number);
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public void increase() {
        
        try{
            lock.lock();
            while (number == 0){
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName()+"\t"+ number);
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
}

public class Version3 {
    public static void main(String[] args) {
        AirConditioner03 airConditioner03 = new AirConditioner03();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                airConditioner03.decrease();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                airConditioner03.increase();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                airConditioner03.decrease();
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                airConditioner03.increase();
            }
        },"D").start();
    }
}

JAVA8 api对此的解释
生产者 / 消费者 面试题生产者 / 消费者 面试题

上一篇:中断唤醒系统流程


下一篇:Matlab实用程序--图形应用-罗盘图