今天面试了一个互联网公司,需要线上考试,由于我一直在忙毕设,也没有时间巩固我的java基础,导致我当时没能把多线程的题做出来。晚上有时间,便来分析…
题目真的超级简单,可是我当然依然没做出来,可能是很久没刷过题了吧。
题目:
输入一组这种形式的数据:
例如 {3 ABC},然后一个线程输出一个字符,那么这组数据就需要创建三个线程,即按照顺序输出3次ABC。
结果应该是:ABCABCABC。
再举个例子:{4 zxc}
那么应该输出:zxczxczxczxc
这个应该听简单的把。可是我竟然没写出了。
直接提供源码吧,给需要的朋友看看。
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @author: raven
* @create: 2020-04-24 13:49
**/
public class Main3 {
public static void main(String[] args) throws InterruptedException, IOException {
String []inputs = {"4 zxcv"};
List<PrintThread> threadList = new ArrayList<>();
for (int i = 0; i < inputs.length; i++) {
String []curr = inputs[i].split(" ");
int soutNum = Integer.parseInt(curr[0]);
int threadSize = curr[1].length();
for (int j = 0; j < threadSize; j++) {
threadList.add(new PrintThread(soutNum, curr[1].charAt(j)));
}
//把线程列表做成一个类似双向链表的数据结构
for (int j = 0 ; j < threadList.size() ; j++) {
//如果是最后一个线程,那么它的下一个线程应该是第一个线程
if(j == threadList.size()-1){
threadList.get(j).setPreviousThread(threadList.get(j-1));
threadList.get(j).setNextThread(threadList.get(0));
}else{
threadList.get(j+1).setPreviousThread(threadList.get(j));
threadList.get(j).setNextThread(threadList.get(j+1));
}
}
//我们开启了第一个线程,所以要设置标志位
threadList.get(0).setFlag(true);
threadList.get(0).start();
}
}
}
class PrintThread extends Thread{
private int num; //字符输出次数
private char signChar;//当前线程输出的字符
private PrintThread previousThread;//前一个线程
private PrintThread nextThread;//后一个线程
private boolean flag = false;//是否已经开始运行
PrintThread(int num, char signChar){
this.num = num;
this.signChar = signChar;
}
@Override
public void run() {
for (int j = 0; j < num; j++) {
try {
//输出当前线程的字符
System.out.print(signChar);
// 如果下一个线程未启动
if(!nextThread.isFlag()){
nextThread.start();
nextThread.setFlag(true);
}else{
//启动的话,直接唤醒它
synchronized (nextThread){
nextThread.notify();
}
}
// 如果不是最后一次输出字符,线程应该等待唤醒,是最后一个字符,那么线程不应该等待。
if(j<num-1){
synchronized (this) {
this.wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public char getSignChar() {
return signChar;
}
public void setSignChar(char signChar) {
this.signChar = signChar;
}
public Thread getNextThread() {
return nextThread;
}
public void setNextThread(PrintThread nextThread) {
this.nextThread = nextThread;
}
public Thread getPreviousThread() {
return previousThread;
}
public void setPreviousThread(PrintThread previousThread) {
this.previousThread = previousThread;
}
}