开启3个线程循环打印10遍ABC-何氏硬刚版+网红版

面试题目+吐槽
  • 我是不知道为什么这个东西一直在面试编码题中吃香,真的。不过真说起来,也没啥好吐槽的,人为刀俎我为鱼肉,你去面试,就得按照别人的评审标准来。你要不乐意,谁也没逼着你。那句经典的台词“咱们今天的面试就到这里吧”,从来都不只是面试官可以说的。
  • 我最大的槽点是,我知道一个题有最佳解法,但也不能忽视别人的劳动成果呀。实不相瞒,我刚离职的这家公司,我当初去面试有一个编码题就是交替顺序打印10遍ABC,我那时候就没写出来。PS:为啥最后还入职了,可能是别的编码题和面试情况拯救了我这道题的失足吧,再此,再次感谢我的领导伙伴。然后我前些天又遇上写这个编码题的公司了,我感觉我写的尽管不能说是完美,但我特别迷惑那面带横肉的一个诡异的冷笑是几个意思,程序员何必难为程序员?
何氏硬刚版
思路
  • 在交替顺序打印10次ABC的时候,A->B->C 其实就是循环的时候既定的执行顺序。假设就有3个人,A只会打印A;B只会打印B;C就会打印C。现在,他们3个人,拿到了一个任务,要完成30个字符的打印。 这种没钱拿的事儿,谁也不愿意多干,谁也不能少干。所以,ABC这3个人,每个人都要出力打印10次自己代表的字符,直到最后一个选手打印出第30个。
  • 关键字:每方出力10次;3方人马必须按照既定顺序执行;一共打印出30个字符。
  • 重点:1,A方第一次打印后,它能不能跑?比如说我打印了第一个“A”,那么在等待BC打印他们各自的字符中,我这段时间能不能跑,比如说去嗑个瓜子啥的。2,我打印完了A,怎么能告诉B?我是自己主动去告诉B呢,还是仇人见面分外眼红,避免伤亡找个中间人呢?3,怎么知道ABC这三个人完成了任务,分别的?完整的?PS:第三点和第二点很像哈。
  • 解答重点的思路:当初我学PV操作的时候,有一个很搞笑的比喻:荒郊野外,只有一个厕所。管你男的还是女的,出一个才能进一个。所以搞个信号灯咯。
  • 就是我如下的代码,获得了面试官的诡异冷笑。唉,现在想想,指不准还真是我too young too simple了,如果有路过的大佬们,发现什么问题的话,就告诉我一声吧。我是觉得我这样也能实现,可能不是很好,但我也没想到会是收获冷笑。
代码
/**
 * @author hehongxia
 */
public class PrintChar {

    private static String currentPrintChar = "A";
    private static int totalTimes = 10;

    public static void main(String[] args) {

        new ThreadPrintA().start();
        new ThreadPrintB().start();
        new ThreadPrintC().start();

        while (true){
            if("Over".equals(currentPrintChar)){
                System.out.println(" 伙计们,干得漂亮,已完成打印任务,撸串去吧。");
                break;
            }
        }

    }

    static class ThreadPrintA extends Thread {

        @Override
        public void run() {
            int printATimes = 0;
            while (printATimes<totalTimes){
                if("A".equals(currentPrintChar) ){
                    System.out.print("A");
                    printATimes++;
                    currentPrintChar = "B";
                }

                if(printATimes==totalTimes){
                    break;
                }
            }
        }
    }

    static class ThreadPrintB extends Thread {

        @Override
        public void run() {
            int printBTimes = 0;
            while (printBTimes<totalTimes){
                if("B".equals(currentPrintChar) ){
                    System.out.print("B");
                    printBTimes++;
                    currentPrintChar = "C";
                }

                if(printBTimes==totalTimes){
                    break;
                }
            }
        }
    }

    static class ThreadPrintC extends Thread {

        @Override
        public void run() {
            int printBTimes = 0;
            while (printBTimes<totalTimes){
                if("C".equals(currentPrintChar)){
                    System.out.print("C");
                    printBTimes++;
                    currentPrintChar = "A";
                }

                if(printBTimes==totalTimes){
                    currentPrintChar="Over";
                    break;
                }
            }
        }
    }
    
}
网红版
思路
  • 就是我上边写的那个实现,收获了冷笑之后,我就一直沉迷在为什么会笑我这个问题上。然后事实上我知道网上大家都说要怎么怎么写,可是我在面试做笔试的时候,我也不知道为什么,真的写不出来,可能是我自己没有真正的去理解领悟到代码的精髓吧。所以我才说,其实要说吐槽,也没啥可吐槽的。各自选择,各自欢喜。
  • 然后在有道云笔记上刮出了我之前面试后回家写的实现代码,嘿嘿,当做纪念咯 。 我有信心,我下次面试要是再遇上这个题,我多半还会写出我上边的代码,哈哈哈,我也很心累,但就是硬刚啊。PS:我能说是有些变量啥的少了一个,然后整张纸上的代码就比较乱,搞得我脑壳子嗡嗡的么。有没有觉得,用笔手写代码,和用IDE写代码感觉不一样啊?无语了我也是。
代码
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author hehongxia
 */
public class PrintChar {
    private static Lock lock = new ReentrantLock();
    private static Condition printA = lock.newCondition();
    private static Condition printB = lock.newCondition();
    private static Condition printC = lock.newCondition();

    private static int printCount = 0;
    private static int totalTimes = 10;
    private static int totalChars = 3;

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(2);

        ThreadPrintA threadPrintA = new ThreadPrintA(countDownLatch);
        ThreadPrintB threadPrintB = new ThreadPrintB(countDownLatch);
        ThreadPrintC threadPrintC = new ThreadPrintC(countDownLatch);

        threadPrintA.start();
        threadPrintB.start();
        threadPrintC.start();

        countDownLatch.await();

        System.out.println(" 交替顺序打印"+totalTimes+"次ABC结束,现在开始干别的了");

    }

    static class ThreadPrintA extends Thread {

        private CountDownLatch countDownLatch ;
        ThreadPrintA(CountDownLatch countDownLatch){
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                lock.lock();
                for (int i = 0; i < totalTimes; i++) {
                    int indexA = 0;
                    while (printCount % totalChars != indexA) {
                        printA.await();
                    }
                    System.out.print("A");
                    printCount++;
                    printB.signal();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                countDownLatch.countDown();
            }
        }
    }

    static class ThreadPrintB extends Thread {

        private CountDownLatch countDownLatch ;
        ThreadPrintB(CountDownLatch countDownLatch){
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                lock.lock();
                for (int i = 0; i < totalTimes; i++) {
                    int indexB = 1;
                    while (printCount % totalChars != indexB) {
                        printB.await();
                    }
                    System.out.print("B");
                    printCount++;
                    printC.signal();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                countDownLatch.countDown();
            }
        }
    }

    static class ThreadPrintC extends Thread {

        private CountDownLatch countDownLatch ;
        ThreadPrintC(CountDownLatch countDownLatch){
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                lock.lock();
                for (int i = 0; i < totalTimes; i++) {
                    int indexC = 2;
                    while (printCount % totalChars != indexC) {
                        printC.await();
                    }
                    System.out.print("C");
                    printCount++;
                    printA.signal();
                }
            } catch (InterruptedException e) {
                lock.unlock();
                countDownLatch.countDown();
            }
        }

    }
    
}
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值