记一个Java多线程相关的面试题
最近一个朋友在找工作,今天给我分享了一个面试题:创建n个线程,循环打印m次(a-z,A-Z,大小写间隔输出) 例如: 3个线程 打印2次(a-z,A-Z) 输出结果 thread1-a,thread2-A,thread3-b。。。。循环两次。大概意思就是创建指定数量n的线程循环打印m次,循环内容是线程依次交错执行,分别从两个共享资源交错取数据。好像越说越乱的样子emmm。。。
最终要的结果如下:
楼主一听题,这还不简单,考的就是多线程的嘛,结果撸了俩小时。。。先贴代码吧。
package com.XXX.manage.modules; import java.util.concurrent.atomic.AtomicInteger; /** * @author JohanChan * @Description TODO * @time 2021/6/3 15:14 */ public class Demo { //需要打印的常量 private static final String[] XXZM = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}; private static final String[] DXZM = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}; private static volatile boolean isXXZM = true;//区分执行数组 private static volatile AtomicInteger count = new AtomicInteger(1);//判断当前要执行的线程 private static volatile AtomicInteger index = new AtomicInteger(0);//打印字母的下标 private static volatile AtomicInteger forCount = new AtomicInteger(0);//循环次数 /** * 功能描述: * TODO * * @param n 线程数量 * @param m 循环次数 * @return void * @author JohanChan * @date 2021/6/3 17:36 */ public static void demo(int n,int m){ if (n > 0 && m > 0){ //每次执行前重置共享资源 isXXZM = true;count.set(1);index.set(0);forCount.set(0); for (int i = 0;i < n;i++){ int thisNUm = i + 1; Thread thread = new Thread(new Runnable() { private final int num = thisNUm;//本线程执行的顺序标识 @Override public void run() { System.out.println("开始执行线程-" + num); //循环次数小于m,打印 while (forCount.get() < m) { print(n, num); } } }); thread.setName("Thread" + thisNUm); thread.start(); } } } /** * 功能描述: * TODO * * @param n 需要执行的线程顺序 * @param num 当前线程顺序标识 * @return void * @author JohanChan * @date 2021/6/3 17:37 */ private static void print(int n,int num){ //获取当前线程 Thread thread = Thread.currentThread(); //判断执行顺序 if (count.get() == num){ synchronized (XXZM){ if (isXXZM){//小写字母 System.out.println(thread.getName() + "-" + XXZM[index.get()]); isXXZM = false; }else{//大写字母 System.out.println(thread.getName() + "-" + DXZM[index.get()]); isXXZM = true; //打印Z后重置下标,循环次数加1 if (index.get() == DXZM.length - 1){ index.set(0);//下标重置为0 forCount.incrementAndGet();//循环次数加1 }else{ index.incrementAndGet();//下标加1 } } //执行线程的顺序标记重置或加1 if (count.get() == n){ count.set(1); }else{ count.incrementAndGet(); } XXZM.notifyAll(); } }else{ try { XXZM.wait(); }catch (Exception e){} } } public static void main(String[] args){ demo(5,10); } }
不得不说,代码要经常撸,这个题没有实际的业务场景支撑,考察的就是多线程相关的应用,楼主有点眼高手低了,以后整理下相关的知识点巩固一下。竟然浪费的两个小时的时间,不说了,下班了,撤!