日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

两个线程如何交替执行,一个输出偶数一个输出奇数?

發(fā)布時(shí)間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 两个线程如何交替执行,一个输出偶数一个输出奇数? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

樓主今天在面經(jīng)上看到這個(gè)題,挺有意思,小小的題目對(duì)多線程的考量還挺多。大部分同學(xué)都會(huì)使用 synchronized 來實(shí)現(xiàn)。

樓主今天帶來另外兩種優(yōu)化實(shí)現(xiàn),讓你面試的時(shí)候,傲視群雄!

synchronized實(shí)現(xiàn)

class?ThreadPrintDemo2?{public?static?void?main(String[] args)?{final?ThreadPrintDemo2 demo2 =?new?ThreadPrintDemo2();Thread t1 =?new?Thread(demo2::print1);Thread t2 =?new?Thread(demo2::print2);t1.start();t2.start();}public?synchronized?void?print2()?{for?(int?i =?1; i <=?100; i +=?2) {System.out.println(i);this.notify();try?{this.wait();Thread.sleep(100);}?catch?(InterruptedException e) {}}}public?synchronized?void?print1()?{for?(int?i =?0; i <=?100; i +=?2) {System.out.println(i);this.notify();try?{this.wait();Thread.sleep(100);}?catch?(InterruptedException e) {}}} }

通過 synchronized 同步兩個(gè)方法,每次只能有一個(gè)線程進(jìn)入,每打印一個(gè)數(shù),就釋放鎖,另一個(gè)線程進(jìn)入,拿到鎖,打印,喚醒另一個(gè)線程,然后掛起自己。循環(huán)反復(fù),實(shí)現(xiàn)了一個(gè)最基本的打印功能。面試常問的:Synchronized 有幾種用法。

但,如果你這么寫,面試官肯定是不滿意的。樓主將介紹一種更好的實(shí)現(xiàn)。

CAS 實(shí)現(xiàn)

?

public?class?ThreadPrintDemo?{static?AtomicInteger cxsNum =?new?AtomicInteger(0);static?volatile?boolean flag =?false;public?static?void?main(String[] args)?{Thread t1 =?new?Thread(() -> {for?(;?100?> cxsNum.get(); ) {if?(!flag && (cxsNum.get() ==?0?|| cxsNum.incrementAndGet() %?2?==?0)) {try?{Thread.sleep(100);}?catch?(InterruptedException e) {}System.out.println(cxsNum.get());flag =?true;}}});Thread t2 =?new?Thread(() -> {for?(;?100?> cxsNum.get(); ) {if?(flag && (cxsNum.incrementAndGet() %?2?!=?0)) {try?{Thread.sleep(100);}?catch?(InterruptedException e) {}System.out.println(cxsNum.get());flag =?false;}}});t1.start();t2.start();} }

我們通過使用 CAS,避免線程的上下文切換,然后呢,使用一個(gè) volatile 的 boolean 變量,保證不會(huì)出現(xiàn)可見性問題,記住,這個(gè) flag 一定要是 volatile 的,如果不是,可能你的程序運(yùn)行起來沒問題,但最終一定會(huì)出問題,而且面試官會(huì)立馬鄙視你。

這樣就消除了使用 synchronized 導(dǎo)致的上下文切換帶來的損耗,性能更好。相信,如果你面試的時(shí)候,這么寫,面試官肯定很滿意。

但,我們還有性能更好的。

volatile實(shí)現(xiàn)

class?ThreadPrintDemo3{static?volatile?int?num =?0;static?volatile?boolean flag =?false;public?static?void?main(String[] args)?{Thread t1 =?new?Thread(() -> {for?(;?100?> num; ) {if?(!flag && (num ==?0?|| ++num %?2?==?0)) {try?{Thread.sleep(100);}?catch?(InterruptedException e) {}System.out.println(num);flag =?true;}}});Thread t2 =?new?Thread(() -> {for?(;?100?> num; ) {if?(flag && (++num %?2?!=?0)) {try?{Thread.sleep(100);}?catch?(InterruptedException e) {}System.out.println(num);flag =?false;}}});t1.start();t2.start();} }

我們使用?volatile?變量代替 CAS 變量,減輕使用 CAS 的消耗,注意,這里 ++num 不是原子的,但不妨礙,因?yàn)橛?flag 變量控制。而 num 必須是 volatile 的,如果不是,會(huì)導(dǎo)致可見性問題。

到這里,如果你面試的時(shí)候這么寫,那么,offer 就不遠(yuǎn)啦!哈哈😆!!

彩蛋:如何翻轉(zhuǎn)字符串?

class?ReverseDemo?{public?static?void?main(String[] args)?{String test =?"abcdefg";System.out.println(new?StringBuilder(test).reverse());char[] arr = test.toCharArray();for?(int?i = arr.length -?1; i >=?0; i--) {System.out.print(arr[i]);}} }

這個(gè)就比較簡(jiǎn)單了,兩種方式,一個(gè)是 StringBuilder 的 reverse 方法,一個(gè)是轉(zhuǎn)換成數(shù)組自己打印。自己轉(zhuǎn)換性能更好,reverse 方法內(nèi)部步驟更多。

好啦,希望大家面試成功!!

作者:莫那·魯?shù)?/p>

來源:cnblogs.com/stateis0/p/9091254.html

總結(jié)

以上是生活随笔為你收集整理的两个线程如何交替执行,一个输出偶数一个输出奇数?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。