面试题:常见的多线程实战手撕代码(顺序打印数字、字母)

版权声明:感谢来访!欢迎指导、勘误、讨论及转载,转载请注明出处 https://blog.csdn.net/u011489043/article/details/80476031

问题一:

  一个多线程的问题,用三个线程,顺序打印字母A-Z,输出结果是1A 2B 3C 1D 2E…打印完毕最后输出一个Ok。

代码一:

public class forCharacter {
    private static char c = 'A';
    private static int i = 0;
    public static void main(String[] args) throws InterruptedException {
        Runnable r = new Runnable() {
            public void run() {
                int threadId = Integer.parseInt(Thread.currentThread().getName());
                while(i < 26){
                    if(i % 3 == threadId - 1){
                        System.out.println("线程id:" + threadId + " " + (char)c++);  
                        i++;
                        if(i == 26)
                            System.out.println("哈哈,祝拿到offer!");
                    }
                    try{
                        Thread.sleep(1000);
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        };
        Thread t1 = new Thread(r, "1");
        Thread t2 = new Thread(r, "2");
        Thread t3 = new Thread(r, "3");
        t1.start();
        t2.start();
        t3.start();
    }
}

  但是代码一存在问题:这样写的话,可能会造成资源浪费,所以我们可以通过加锁进行限制,但是加锁后,因为sleep不会释放锁,会导致其他线程无法获得执行机会。因此需要配合wait和notifyAll。

代码二:

public class forCharacter {
    /*
     * Description:一个多线程的问题,用三个线程,顺序打印字母A-Z,输出结果是1A 2B 3C 1D 2E...打印完毕最后输出一个Ok
     * Author:ZhangRuirui 
     * Date:2018/05/25 
     * Email:[email protected]
     */
    private static char c = 'A';// 必要的时候声明为volatile类型的
    private static int i = 0;

    public static void main(String[] args) throws InterruptedException {
        Runnable r = new Runnable() {
            public void run() {
                synchronized (this) {
                    try {
                        int threadId = Integer.parseInt(Thread.currentThread().getName());
                        System.out.println("当前线程id:" + threadId + " ");
                        while (i < 26) {
                            if (i % 3 == threadId - 1) {
                                System.out.println("线程id:" + threadId + " " + (char) c++);
                                i++;
                                if (i == 26)
                                    System.out.println("哈哈,祝拿到offer!");
                                notifyAll();// 唤醒其他线程
                            } else {
                                wait();// 阻塞其他线程
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t1 = new Thread(r, "1");
        Thread t2 = new Thread(r, "2");
        Thread t3 = new Thread(r, "3");
        t1.start();
        t2.start();
        t3.start();
    }
}

输出:

当前线程id1 
线程id1 A
当前线程id2 
线程id2 B
当前线程id3 
线程id3 C
线程id1 D
线程id2 E
线程id3 F
线程id1 G
线程id2 H
线程id3 I
线程id1 J
线程id2 K
线程id3 L
线程id1 M
线程id2 N
线程id3 O
线程id1 P
线程id2 Q
线程id3 R
线程id1 S
线程id2 T
线程id3 U
线程id1 V
线程id2 W
线程id3 X
线程id1 Y
线程id2 Z
哈哈,祝拿到offer!

问题二:(快手)

  一个多线程的问题,用五个线程,顺序打印数字1~无穷大,其中每5个数字为1组,如下:其中id代表线程的id

id   1   2   3   4   5
no   1   2   3   4   5
no   6   7   8   9   10
no   11  12  13  14  15
no   ..  ..  ..  ..  ..

代码:

public class forCharacter2 {

    /*
     * Description:一个多线程的问题,用五个线程,顺序打印数字1~无穷大,其中每5个数字为1组 
     * Author:ZhangRuirui
     * Date:2018/05/25 
     * Email:[email protected]
     */
    private static volatile int orderNum = 1;// 必要的时候声明为volatile类型的

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                synchronized (this) {
                    try {
                        int threadId = Integer.parseInt(Thread.currentThread().getName());
                        while (true) {
                            if (orderNum % 5 == threadId || orderNum % 5 == 0) {
                                if (orderNum % 5 == 0)
                                    System.out.println("threadid = " + 5 + " " + orderNum++);
                                else
                                    System.out.println("threadid = " + threadId + " " + orderNum++);
                                Thread.sleep(1000);// 为了执行效果看的更清楚
                                notifyAll();
                            } else {
                                wait();
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Thread t1 = new Thread(r, "1");
        Thread t2 = new Thread(r, "2");
        Thread t3 = new Thread(r, "3");
        Thread t4 = new Thread(r, "4");
        Thread t5 = new Thread(r, "5");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

输出:

threadid = 1 1
threadid = 2 2
threadid = 3 3
threadid = 4 4
threadid = 5 5
threadid = 1 6
threadid = 2 7
threadid = 3 8
threadid = 4 9
threadid = 5 10
threadid = 1 11
threadid = 2 12
threadid = 3 13
threadid = 4 14
threadid = 5 15
threadid = 1 16
threadid = 2 17
下面死循环不断输出

—–乐于分享,共同进步,欢迎补充
—–Any comments greatly appreciated
—–诚心欢迎各位交流讨论!QQ:1138517609

猜你喜欢

转载自blog.csdn.net/u011489043/article/details/80476031