面试宝典(三):如何使用两个线程实现服务提供和服务消费

提起来面试,可能被问的最多的之一,就是多线程了。比如下面的的这个招聘要求,便提到了多线程。

面试宝典(三):如何使用两个线程实现服务提供和服务消费_第1张图片

更有甚者,虽聊聊数语,但对于多线程这个技能的要求,甚至提升到了首位的程度,其看重程度可见一斑。

面试宝典(三):如何使用两个线程实现服务提供和服务消费_第2张图片

那么本次我们便来讲一个多线程常见的面试题:如何用两个线程,实现服务提供和服务消费,即一个线程用作服务提供,一个线程用作服务消费?

话不多说,直接来看示例代码:

public class ThreadTest1 {

    public static volatile int amount = 0;

    public static void main(String[] args) {
        Thread threadProducer = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("---------我要生产包子了---------");
                    amount = amount + 1;
                    System.out.println("---------包子生产完了---------");

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        threadProducer.start();

        Thread threadConsumer = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("---------我要买包子---------");
                    if (amount == 0) {
                        System.out.println("---------包子卖完了---------");
                        System.out.println("---------等一会儿吧---------");
                    } else {
                        System.out.println("---------包子还有---------");
                        amount = amount - 1;
                        System.out.println("---------包子买过了---------");
                    }

                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        threadConsumer.start();
    }

}

就以买包子为例,服务提供线程用于生产包子,包子初始数量为0,每隔1秒生产一个包子。服务消费线程用于买包子,当包子数量为0时,不做处理,等待包子生产完成;当包子数量为1时,包子数量减1,买包子成功

程序运行效果如下:

面试宝典(三):如何使用两个线程实现服务提供和服务消费_第3张图片

但是,这样还是不够直观,我们想办法让买包子变成随机数量,来让两个线程“动起来”。

public class ThreadTest2 {

    public static volatile int amount = 0;

    public static void main(String[] args) {
        Thread threadProducer = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("---------我要生产包子了---------");
                    amount = amount + 1;
                    System.out.println("---------包子 + 1,现在有 " + amount + "个包子---------");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        threadProducer.start();

        Thread threadConsumer = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    int amount_consumer = new Random().nextInt(9);

                    if (amount_consumer == 0) {
                        System.out.println("---------不好意思,我不买子---------");
                    } else {
                        System.out.println("---------我要买" + amount_consumer + "个包子---------");
                        if (amount_consumer > amount) {
                            System.out.println("---------包子不够,等一会儿吧---------");
                        } else {
                            amount = amount - amount_consumer;
                            System.out.println("---------包子买过了,买了" + amount_consumer + "个包子,还有 " + amount + "个包子---------");
                        }
                    }


                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        threadConsumer.start();
    }
    
}

同样的,服务提供线程用于生产包子,包子初始数量为0,每隔1秒生产一个包子。服务消费线程用于买包子,每次买包子的数量为随机数值。当包子数量为0或当包子数量小于本次要够买的数量时,均不做处理;当包子数量刚好大于等于本次要够买的数量时,包子数量减去本次要够买的数量,买包子成功

来看一下运行效果:

面试宝典(三):如何使用两个线程实现服务提供和服务消费_第4张图片

看吧,两个线程“动起来”了吧?

至于示例代码中的 volatile 关键字,何不自己动手查一下呢?印象更深哦!感兴趣的也可以把这个关键字去掉,看这两个示例分别是什么样的运行结果。

我是银河架构师,十年饮冰,难凉热血,愿历尽千帆,归来仍是少年! 

如果文章对您有帮助,请举起您的小手,轻轻【三连】,这将是笔者持续创作的动力源泉。当然,如果文章有错误,或者您有任何的意见或建议,请留言。感谢您的阅读!

 

你可能感兴趣的:(多线程,日积月累,程序人生,1024程序员节,java,并发编程,多线程)