21xrx.com
2024-12-22 21:15:35 Sunday
登录
文章检索 我的文章 写文章
《小米Java工程师笔试——一道经典的多线程问题》
2023-06-19 03:49:41 深夜i     --     --
小米 Java工程师 多线程

在小米Java工程师笔试中,面试官经常会问到多线程相关的问题。今天我们来讲一道经典的多线程问题,也是小米笔试中的一道常见题目。

问题描述:

现在有三个线程T1、T2、T3,其中T1、T2、T3分别输出字母A、B、C,要求线程间隔次序输出,即输出的结果应该为ABCABCABC... 依次递推,循环10次。

首先,我们来思考一下如何保证三个线程的输出次序。我们可以使用Java中的wait()和notify()方法来实现线程间的协作。具体来说,我们可以使用一个信号量标记当前应该执行哪个线程,每个线程执行完后调用notify()方法通知下一个线程执行,然后当前线程调用wait()方法等待下一次被通知。

下面是代码实现:


public class PrintABC implements Runnable {

  private static int signal = 1;

  private int count;

  public PrintABC(int count)

    this.count = count;

  

  @Override

  public void run() {

    for (int i = 0; i < count; i++) {

      synchronized (PrintABC.class) {

        while (signal != getTarget()) {

          try {

            PrintABC.class.wait();

          } catch (InterruptedException e) {

            e.printStackTrace();

          }

        }

        System.out.print(getChar());

        signal = getNext();

        PrintABC.class.notifyAll();

      }

    }

  }

  private static char getChar() {

    return (char) (signal + 'A' - 1);

  }

  private static int getTarget()

    return signal;

  

  private static int getNext() {

    return signal % 3 + 1;

  }

  public static void main(String[] args) {

    new Thread(new PrintABC(10)).start();

    new Thread(new PrintABC(10)).start();

    new Thread(new PrintABC(10)).start();

  }

}

上述代码中,我们使用了一个静态变量signal来标记当前应该执行哪个线程。接下来的getChar()、getTarget()和getNext()方法分别用于获取当前线程应该输出的字符、当前线程的编号和下一个应该执行的线程编号。在run()方法中,我们使用synchronized关键字加锁,并在循环中不断检查signal属性,若当前线程的编号不等于signal属性值,就调用wait()方法等待被唤醒。当signal等于当前线程的编号时,输出相应的字符,并调用notifyAll()方法唤醒下一个线程执行。

通过这个例子,我们可以看到多线程编程需要的是对于同步锁以及对于wait()和notify()方法的理解。在笔试及面试中,多线程问题是一个常见的考察点,我们需要熟练掌握Java中的线程操作,且多写一些多线程的代码例子。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复