多線程如何循環(huán)順序打印“ABABAB”

解題思路

使用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工具

    /**
     * 掛起當(dāng)前線程。(當(dāng)其許可可用時,恢復(fù)線程執(zhí)行,由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();
    }
}

三、總結(jié)
synchronized+線程notify/wait 方式在于喚醒隨機一個線程,而LockSupport可以控制喚醒哪個線程。
除此之外,LockSupport還支持設(shè)置線程是由什么對象阻塞的,在部分場景排查問題提供了幫助。
上面LockSupport的方法中在使用park方法都指定了blocker為一個子符串,通過線程dump可以發(fā)現(xiàn) *** parking to wait for <0x00000000d7d97468> (a java.lang.String)*** 是由地址為0x00000000d7d97468的字符串阻塞的。

blocker.png

end

歡迎提供好的思路和指正問題,哈哈。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容