记一个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);
    }

}

  不得不说,代码要经常撸,这个题没有实际的业务场景支撑,考察的就是多线程相关的应用,楼主有点眼高手低了,以后整理下相关的知识点巩固一下。竟然浪费的两个小时的时间,不说了,下班了,撤!

 

posted @ 2021-06-03 18:54  胜金  阅读(107)  评论(0编辑  收藏  举报