昨天面试面试官问了我一个多线程问题,说有两个数组,一个里面是ABCDEFG,另一个里面是1234567,现在用两个线程分别打印这两个数组,要求打印一个字母再打印一个数组,问我怎么实现。
我当时第一反应就是通过wait方法来实现,但是面试官说wait方法不行,notify会唤醒所有线程,所以有可能会继续执行当前线程,由于我对线程这块也不熟悉,当时没有发现哪里不对,今天写了个demo测试了下,发现是可以实现的,代码如下:
package com.example.demo.test;
public class ArrayPrinter {
private static final Object lock = new Object(); // 用于线程同步的锁对象
private static final char[] letters = {'A', 'B', 'C', 'D', 'F', 'F', 'G'};
private static final int[] numbers = {1, 2, 3, 4, 5, 6, 7};
private static volatile int index = 0; // 当前要打印的索引
public static void main(String[] args) {
Thread letterThread = new Thread(() -> {
for (char letter : letters) {
synchronized (lock) {
try {
while (index % 2 != 0) {
lock.wait(); // 如果不是字母的打印顺序,则等待
}
System.out.print(letter);
index++;
lock.notify(); // 唤醒数字线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread numberThread = new Thread(() -> {
for (int number : numbers) {
synchronized (lock) {
try {
while (index % 2 != 1) {
lock.wait(); // 如果不是数字的打印顺序,则等待
}
System.out.print(number);
index++;
lock.notify(); // 唤醒字母线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
letterThread.start();
numberThread.start();
}
}
执行结果:
A1B2C3D4F5F6G7
Process finished with exit code 0
最后,notify方法是唤醒等待线程中的一个线程,notifyall是唤醒全部等待线程