Java-多线程

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

2020-07-26  本文已影响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

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

上一篇下一篇

猜你喜欢

热点阅读