题目
最近面试遇到一个多线程的题目,对方要求用多个线程打印ABCABC…,每个线程负责打印其中一个字母。循环10次吧!
题解
public class Test {
public static void main(String[] args) {
String[] names = new String[]{"A", "B", "C"};
Thread[] threads = new Thread[3];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new PrintThread(i, names[i]));
threads[i].start();
}
}
}
/**
* 打印线程
*/
class PrintThread implements Runnable {
/** 全局变量,存储打印的总次数 */
private static int n;
/** 当前线程的顺序号,各线程按顺序打印 */
private int index;
/** 当前线程要打印的信息 */
private String msg;
public PrintThread(int index, String msg) {
this.index = index;
this.msg = msg;
}
@Override
public void run() {
//只需要打印10*3=30次,也可以将条件换为true一直打印
while (n < 30) {
if (n % 3 == index) {
System.out.print(msg);
n++;
} else {
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
反馈
代码写完后,我立即拿给面试官,顺便对照代码给他讲了一个我的解题思路,结果讲完以后他说我这个不对,打出来不是ABCABC这样循环的。这个题需要用到线程间通信。我知道他的解题思路,下面附上线程通信方式的代码。但在这之前,我想说的是这个题目的解决方法有多种,只要能够符合题目要求的代码应该都是合格的。
不过,我之前好像也看到这上述多线程代码存在一些风险,但一时又想不起来了。如果有哪位朋友对此有更深的见解,欢迎留言指导。
线程间通信
/**
* 打印线程
*/
class PrintThread implements Runnable {
/** 全局变量,存储打印的总次数 */
private static int n;
private static Object obj = new Object();
/** 当前线程的顺序号,各线程按顺序打印 */
private int index;
/** 当前线程要打印的信息 */
private String msg;
public PrintThread(int index, String msg) {
this.index = index;
this.msg = msg;
}
@Override
public void run() {
synchronized (obj) {
while (n < 30) {
if (n % 3 == index) {
System.out.print(msg);
n++;
obj.notifyAll();
} else {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
测试代码跟上述基本一样,这里就不再重复啦!