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

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

  • 相关阅读:
    20150515
    20150509
    20150507
    好用的log打印类
    20150429
    Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
    word无法切换中文输入法的解决方法
    20140917设置动态壁纸
    WCF入门教程(三)定义服务协定--属性标签
    WCF入门教程(二)从零做起-创建WCF服务
  • 原文地址:https://www.cnblogs.com/JohanChan/p/14846490.html
Copyright © 2020-2023  润新知