• Java面试题:多线程交替打印字符串


    这道题是字节的面试题,当场问我有点紧张没想出来,只答上来要交替阻塞,还是面试官提醒我用生产者消费者思路解决。

    题目

    有A类线程50个,任务是打印字符A。有B类线程50个,任务是打印字符B。现在异步启动这100个线程,问如何才能让他们交替打印AB字符?

    解题思路

    设两个信号SemaphoreA和SemaphoreB,他们代表A类和B类的资源数且他们的上限各有一个。初始设SemaphoreA=1,SemaphoreB=0。当一个A类线程消费完SemaphoreA生产一个B类资源:SemaphoreB++。此时其他A类线程进入阻塞,某一B线程开始获取资源打印。当一个B类线程消费完SemaphoreB,生产一个A类资源:SemaphoreA++。此后循环交替打印。该题的难点在于是否想到生产者消费者。

    实践

    这道题LeetCode上有,我就刷了下:https://leetcode-cn.com/problems/print-foobar-alternately/

    描述

    两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。请设计修改程序,以确保 "foobar" 被输出 n 次。

    代码

    class FooBar {
        private int n;
        private Semaphore semaphoreFoo = new Semaphore(1);
        private Semaphore semaphoreBar = new Semaphore(0);
    
        public FooBar(int n) {
            this.n = n;
        }
    
        public void foo(Runnable printFoo) throws InterruptedException {
    
            for (int i = 0; i < n; i++) {
                semaphoreFoo.acquire();
                // printFoo.run() outputs "foo". Do not change or remove this line.
                printFoo.run();
                semaphoreBar.release();
            }
        }
    
        public void bar(Runnable printBar) throws InterruptedException {
    
            for (int i = 0; i < n; i++) {
                semaphoreBar.acquire();
                // printBar.run() outputs "bar". Do not change or remove this line.
                printBar.run();
                semaphoreFoo.release();
            }
        }
    }
     
  • 相关阅读:
    Genbank简介
    Asc码与字符互相转化
    Netbeans中文乱码
    弹出警告窗口
    PHP代码执行漏洞总结
    透析SCN
    oracle用户管理的完全恢复4:在ARCHIVELOG 模式(恢复打开的数据库数据库最初是关闭的)
    Oracle用户管理的不完全恢复2:基于取消的恢复
    RMAN备份详解1
    oracle用户管理的完全恢复6:控制文件损坏(控制文件前后内容改变)
  • 原文地址:https://www.cnblogs.com/billshen/p/13265320.html
Copyright © 2020-2023  润新知