Java实现两个线程交替打印一个字符串
面试时经常会遇到这类问题,可以用一些小例子来熟悉多线程的使用以及Object的wait和notify等相关知识。
回到这题:
- 首先我们需要一个字符串,可以拆分成数组或者List
- 其次我们需要一把锁,用于控制字符串的有序打印
- 最后我们还需要一个指针,用于线程间通信(通知打印到哪里了)
代码如下:
线程a打印字符串方法:
public static void printStringA(String[] strs) throws InterruptedException {
while (strs.length > index) {
synchronized (LOCK) {
if (index % 2 == 0) {
log.info(Thread.currentThread().getName() + ": " +strs[index]);
index++;
// notify 随机唤醒一个持有该锁的其他线程
LOCK.notify();
} else {
// 阻塞当前线程
LOCK.wait();
}
}
}
}
线程b打印字符串方法:
public static void printStringB(String[] strs) throws InterruptedException {
while (strs.length > index) {
synchronized (LOCK) {
if (index % 2 == 1) {
log.info(Thread.currentThread().getName() + ": " +strs[index]);
index++;
LOCK.notify();
} else {
LOCK.wait();
}
}
}
}
mian方法测试:
/**
* 打印字符串的锁
*/
private static final Object LOCK = new Object();
/**
* 控制打印位置的指针
*/
private static volatile int index = 0;
/**
* 打印的线程池
*/
static ExecutorService executor = Executors.newFixedThreadPool(2);
public static void main(String[] args) {
var str = "我是个大帅逼";
var strs = str.split("");
executor.execute(() -> {
try {
printStringA(strs);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.execute(() -> {
try {
printStringB(strs);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.shutdown();
}
测试效果如下: