阿里面试题:123顺序打印

442 阅读1分钟

题目:两个线程交替输出1,2,3,4,5。

两个线程交替输出解法

面试官出这个题目只是想考察你能否理解notify、wait的使用。只要我们事先决定出哪个线程先执行即可。

/**
 * @author: sanjin
 * @date: 2021/11/16 11:55 下午
 */
public class Main {
    static int i = 0;
    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new PrintThread("t1", true);
        Thread t2 = new PrintThread("t2", false);
        t2.start();
        t1.start();
        t2.join();
        t1.join();
    }

    static class PrintThread extends Thread {
        private boolean isFirst;

        public PrintThread(String name, boolean isFirst) {
            super(name);
            this.isFirst = isFirst;
        }

        @Override
        public void run() {
            synchronized (lock) {
                while (true) {
                    if (!isFirst) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        isFirst = true;
                    }
                    System.out.println(getName() + ",i=" + (++i));
                    lock.notify();
                    try {
                        lock.wait();
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

多个线程顺序打印

上面是两个线程的解决方法,如果有N个线程呢,比如5个线程? 我们使用数组存储线程,用下标表示正在执行的线程,使用LockSupport的park+unpark做到指定线程唤醒。


/**
 * @author: sanjin
 * @date: 2021/11/16 11:55 下午
 */
public class Main2 {
    static int i = 0;
    static List<Thread> threads = new ArrayList<>();
    static int index = 0;

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new PrintThread("t1", true);
        Thread t2 = new PrintThread("t2", false);
        Thread t3 = new PrintThread("t3", false);
        Thread t4 = new PrintThread("t4", false);
        threads.add(t1);
        threads.add(t2);
        threads.add(t3);
        threads.add(t4);
        t2.start();
        t1.start();
        t3.start();
        t4.start();
        t2.join();
        t1.join();
    }

    static class PrintThread extends Thread {
        private boolean isFirst;

        public PrintThread(String name, boolean isFirst) {
            super(name);
            this.isFirst = isFirst;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (!isFirst) {
                    LockSupport.park();
                    isFirst = true;
                }
                System.out.println(getName() + ",i=" + (++i));
                LockSupport.unpark(threads.get(++index % threads.size()));
                LockSupport.park();
            }
        }
    }
}