阿里的一道线程面试题,面哭了无数人

很多人都想进 BAT,但是并不是每个人都能如愿。BAT 的面试非常的严格,今年春招,阿里的一道线程面试题,就淘汰了无数的人!

今天我对这道题,分别用了 3 种不同的方法实现了,供大家参考!

题目如下:

通过N个线程顺序循环打印从0至100,如给定N=3则输出:
thread0: 0
thread1: 1
thread2: 2
thread0: 3
thread1: 4
…..

第一种,通过判断执行状态来实现。

static int result = 0;
public static void orderPrintNum(final int n){
    final boolean [] printFlag = new boolean [n];
    for (int i = 0; i < n; i++) {
        final int index = i;
        if(0 == i){
            printFlag[index] = true;
        }
        new Thread(new Runnable() {
            public void run() {
                try {
                    while (result <= 100) {
                        if(printFlag[index]){
                            System.out.println("thread" + index + ": " + result++);
                            printFlag[index] = false;
                            if(index == (n - 1)){
                                printFlag[0] = true;
                            }else {
                                printFlag[index + 1] = true;
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }).start();
    }
}

想到这种方式的,应该就能想到信号量。因此,第二种实现方法就是通过信号量来实现。

static int result = 0;
public static void orderPrintNum2(final int n) throws InterruptedException{
    // N 个线程
    Thread [] threads = new Thread[n];
    // N 个Semaphore
    final Semaphore[] syncSemaphore = new Semaphore[n];
    for (int i = 0; i < n; i++) {
        //非公平信号量,计数为1
        syncSemaphore[i] = new Semaphore(1);
        if (i != n-1){
            //获取一个许可前线程将一直阻塞
            syncSemaphore[i].acquire();
        }
    }
    for (int i = 0; i < n; i++) {
        final Semaphore lastSemphore = i == 0 ? syncSemaphore[n - 1] : syncSemaphore[i - 1];
        final Semaphore curSemphore = syncSemaphore[i];
        final int index = i;
        threads[i] = new Thread(new Runnable() {
            public void run() {
                try {
                    while (true) {
                        lastSemphore.acquire();
                        System.out.println("thread" + index + ": " + result++);
                        if (result > 100){
                            System.exit(0);
                        }
                        curSemphore.release();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });
        threads[i].start();
    }
}

第三种,通过 wait 和 notifyAll 来实现。

static int result = 0;
public static void orderPrintNum3(final int n) {
    final Object LOCK = new Object();
    final int [] flag = new int[1];
    for (int i = 0;i < n; i++){
        final int index = i;
        new Thread(new Runnable() {
            public void run() {
                try {
                    while (result <= 100) {
                        synchronized (LOCK){
                            if(flag[0] == index){
                                System.out.println("thread" + index + ": " + result++);
                                flag[0] = index == n - 1 ? 0 : index + 1;
                                // 唤醒其他wait线程
                                LOCK.notifyAll();
                            }else {
                                LOCK.wait();
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

3 种方法的运行效果,截图如下:

线程笔试题

除此之外,还可以通过队列,链表等形式来实现。具体,大家去思考思考吧!

阿里的一道线程面试题,面哭了无数人

: » 阿里的一道线程面试题,面哭了无数人

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/tech/java/252054.html

(0)
上一篇 2022年5月3日 23:47
下一篇 2022年5月3日 23:51

相关推荐

发表回复

登录后才能评论