美文网首页Java-多线程
多线程如何循环顺序打印“ABABAB”

多线程如何循环顺序打印“ABABAB”

作者: 超人也害羞 | 来源:发表于2020-07-26 13:49 被阅读0次

    解题思路

    使用synchronized和线程notify/wait
    使用LockSupport

    一、synchronized+线程notify/wait

    public class TestLockSupport {
        static Thread t1 = null;
        static Thread t2 = null;
        public static void main(String[] args) {
            useThread();
        }
    
        private static void useThread() {
            int times = 100;
            t1 = new Thread("测试线程-1") {
                @Override
                public void run() {
                    for (int i = 0; i < times; i++) {
                        synchronized (TestLockSupport.class) {
                            try {
                                System.out.println("A");
                                TestLockSupport.class.notify();
                                TestLockSupport.class.wait();
                            } catch (InterruptedException e) {
                            }
                        }
                    }
                }
            };
            t2 = new Thread("测试线程-2") {
                @Override
                public void run() {
                    for (int i = 0; i < times; i++) {
                        synchronized (TestLockSupport.class) {
                            try {
                                System.out.println("B");
                                TestLockSupport.class.notify();
                                TestLockSupport.class.wait();
                            } catch (InterruptedException e) {
                            }
                        }
                    }
                }
            };
            t1.start();
            t2.start();
        }
    }
    

    二、LockSupport工具

        /**
         * 挂起当前线程。(当其许可可用时,恢复线程执行,由unpark()唤醒)
         */
        public static void park() {
            UNSAFE.park(false, 0L);
        }
      
        /**
         * 通知指定线程其许可证可用(也可以说唤醒指定线程)。
         */
        public static void unpark(Thread thread) {
            if (thread != null)
                UNSAFE.unpark(thread);
        }
    
    public class TestLockSupport {
        static Thread t1 = null;
    
        static Thread t2 = null;
    
        public static void main(String[] args) {
            int times = 100000;
            String tmp = "abc";
            String tmp2 = "efg";
            t1 = new Thread("测试线程-1") {
                @Override
                public void run() {
                    for (int i = 0; i < times; i++) {
                        try {
                            Thread.sleep(1000L);
                            System.out.println("A");
                        } catch (InterruptedException e) {
                        }
                        LockSupport.unpark(t2);
                        LockSupport.park(tmp);
                    }
                }
            };
            t2 = new Thread("测试线程-2") {
                @Override
                public void run() {
                    for (int i = 0; i < times; i++) {
                        LockSupport.park(tmp2);
                        try {
                            Thread.sleep(1000L);
                        } catch (InterruptedException e) {
                        }
                        System.out.println("B");
                        LockSupport.unpark(t1);
                    }
                }
            };
            t1.start();
            t2.start();
        }
    }
    

    三、总结
    synchronized+线程notify/wait 方式在于唤醒随机一个线程,而LockSupport可以控制唤醒哪个线程。
    除此之外,LockSupport还支持设置线程是由什么对象阻塞的,在部分场景排查问题提供了帮助。
    上面LockSupport的方法中在使用park方法都指定了blocker为一个子符串,通过线程dump可以发现 *** parking to wait for <0x00000000d7d97468> (a java.lang.String)*** 是由地址为0x00000000d7d97468的字符串阻塞的。

    blocker.png

    end

    欢迎提供好的思路和指正问题,哈哈。

    相关文章

      网友评论

        本文标题:多线程如何循环顺序打印“ABABAB”

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