美文网首页并发
两个线程循环打印数字字母的问题

两个线程循环打印数字字母的问题

作者: gigglesoso | 来源:发表于2020-05-05 22:05 被阅读0次

    一道经典的多线程面试题:

    两个线程,一个线程打印1-26,另一个线程打印A-Z,但是需要的效果是两个线程交替打印,产生效果如1A2B………26Z的效果。

    • 思考:这个其实考察了两个线程间的通信问题。

    思路如下:需要实现两个线程,重写run方法,run方法内部需要26次for循环,分别打印数字和字母,但是需要线程1(打印1)阻塞,切换到线程2(打印A)阻塞,切换到线程1(打印2)……

    • 方法一,使用synchronized解决:
    package demo;
    
    
    /**
     * 循环打印1A2B……
     * @author Gxp
     *
     */
    public class A1B2_syn {
        // 定义一个锁
        static Object lock = new Object();
        // 定义两个线程
        static Thread number = new Thread(()->{
            // 线程内部方法需要加synchronized,锁定lock对象
            synchronized (lock) {
                for (int i = 1; i < 27; i++) {
                    System.out.print(i);
                    // 打印出一个后,先唤醒其他线程
                    lock.notifyAll();
                    try {
                        // 阻塞当前线程,并且释放锁,这里判断是最后的边界条件,最后一次输出当前线程就不需要阻塞了
                        if (i != 25) {
                            lock.wait();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        
        static Thread letter = new Thread(()->{
            synchronized (lock) {
                for (int i = 0; i < 26; i++) {
                    System.out.print((char)('A'+i));
                    lock.notifyAll();
                    try {
                        // 这里一定要判断边界条件,假如是最后一个输出,则不需要阻塞,直接结束就好了,否则该线程会一直阻塞
                        if (i != 25) {
                            lock.wait();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        
        
        public static void main(String[] args) {
            number.start();
            // 保证线程letter线程先运行
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            letter.start();
        }
    }
    
    
    • 方法二:通过Lock和Conditon实现
    package demo;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 循环打印1A2B……  使用lock实现
     * @author Gxp
     *
     */
    public class A1B2_lock {
        
        static Lock lock = new ReentrantLock();
        static Condition letter = lock.newCondition();
        static Condition number = lock.newCondition();
        
        static Thread numberThread = new Thread(()->{
            try {
                lock.lock();
                for (int i = 0; i < 26; i++) {
                    System.out.print(i+1);
                    // 需要先唤醒letter线程
                    letter.signal();
                    // 然后再阻塞自己
                    if (i != 25) {
                        number.await();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });
        
        
        static Thread letterThread = new Thread(()->{
            try {
                lock.lock();
                for (int i = 0; i < 26; i++) {
                    System.out.print((char)('A'+i));
                    number.signal();
                    if (i != 25) {
                        letter.await();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });
        
        public static void main(String[] args) {
            numberThread.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            letterThread.start();
        }
    }
    
    
    

    相关文章

      网友评论

        本文标题:两个线程循环打印数字字母的问题

        本文链接:https://www.haomeiwen.com/subject/mnavghtx.html