來源:cnblogs.com/stateis0/p/9091254.html
前言
樓主今天在面經上看到這個題,挺有意思,小小的題目對多線程的考量還挺多。大部分同學都會使用 synchronized 來實現。樓主今天帶來另外兩種優化實現,讓你面試的時候,傲視群雄!
第一種 synchronized
![兩個線程如何交替執行,一個輸出偶數一個輸出奇數?](http://p2.ttnews.xyz/loading.gif)
![兩個線程如何交替執行,一個輸出偶數一個輸出奇數?](http://p2.ttnews.xyz/loading.gif)
通過 synchronized 同步兩個方法,每次只能有一個線程進入,每打印一個數,就釋放鎖,另一個線程進入,拿到鎖,打印,喚醒另一個線程,然後掛起自己。循環反覆,實現了一個最基本的打印功能。
但,如果你這麼寫,面試官肯定是不滿意的。樓主將介紹一種更好的實現。
使用 CAS 實現
我們通過使用 CAS,避免線程的上下文切換,然後呢,使用一個 volatile 的 boolean 變量,保證不會出現可見性問題,記住,這個 flag 一定要是 volatile 的,如果不是,可能你的程序運行起來沒問題,但最終一定會出問題,而且面試官會立馬鄙視你。
這樣就消除了使用 synchronized 導致的上下文切換帶來的損耗,性能更好。相信,如果你面試的時候,這麼寫,面試官肯定很滿意。
但,我們還有性能更好的。
使用 volatile
我們使用 volatile 變量代替 CAS 變量,減輕使用 CAS 的消耗,注意,這裡 ++num 不是原子的,但不妨礙,因為有 flag 變量控制。而 num 必須是 volatile 的,如果不是,會導致可見性問題。
到這裡,如果你面試的時候這麼寫,那麼,offer 就不遠啦!哈哈!!
彩蛋 如何翻轉字符串?
這個就比較簡單了,兩種方式,一個是 StringBuilder 的 reverse 方法,一個是轉換成數組自己打印。自己轉換性能更好,reverse 方法內部步驟更多。
好啦,希望大家面試成功!!
閱讀更多 程序員BUG 的文章