【高并發(fā)】為什么局部變量是線程安全的?

      網(wǎng)友投稿 777 2025-03-31

      大家好,我是冰河~~


      相信很多小伙伴都知道局部變量是線程安全的,那你知道為什么局部變量是線程安全的嗎?

      前言

      多個(gè)線程同時(shí)訪問共享變量時(shí),會(huì)導(dǎo)致并發(fā)問題。那么,如果將變量放在方法內(nèi)部,是不是還會(huì)存在并發(fā)問題呢?如果不存在并發(fā)問題,那么為什么不會(huì)存在并發(fā)問題呢?

      著名的斐波那契數(shù)列

      記得上學(xué)的時(shí)候,我們都會(huì)遇到這樣一種題目,打印斐波那契數(shù)列。斐波那契數(shù)列是這樣的一個(gè)數(shù)列:1、1、2、3、5、8、13、21、34…,也就是說第1項(xiàng)和第2項(xiàng)是1,從第3項(xiàng)開始,每一項(xiàng)都等于前2項(xiàng)之和。我們可以使用下面的代碼來生成斐波那契數(shù)列。

      //生成斐波那契數(shù)列 public int[] fibonacci(int n){ //存放結(jié)果的數(shù)組 int[] result = new int[n]; //數(shù)組的第1項(xiàng)和第2項(xiàng)為1 result[0] = result[1] = 1; //計(jì)算第3項(xiàng)到第n項(xiàng) for(int i = 2; i < n; i++){ result[i] = result[i-2] + result[i-1]; } return result; }

      假設(shè)此時(shí)有很多個(gè)線程同時(shí)調(diào)用fibonacci()方法來生成斐波那契數(shù)列,

      對(duì)于方法中的局部變量result,會(huì)不會(huì)存在線程安全的問題呢?答案是:不會(huì)??!

      接下來,我們就深入分析下為什么局部變量不會(huì)存在線程安全的問題!

      方法是如何被執(zhí)行的?

      我們以下面的三行代碼為例。

      int x = 5; int[] y = fibonacci(x); int[] z = y;

      當(dāng)我們調(diào)用fibonacci(x)時(shí),CPU要先找到fibonacci()方法的地址,然后跳轉(zhuǎn)到這個(gè)地址去執(zhí)行代碼,執(zhí)行完畢后,需要返回并找到調(diào)用方法的下一條語句的地址,也就是int[] z = y的地址,再跳到這個(gè)地址去執(zhí)行。我們可以將這個(gè)過程簡化成下圖所示。

      這里需要注意的是:CPU會(huì)通過堆棧寄存器找到調(diào)用方法的參數(shù)和返回地址。

      例如,有三個(gè)方法A、B、C,調(diào)用關(guān)系為A調(diào)用B,B調(diào)用C。在運(yùn)行時(shí),會(huì)構(gòu)建出相應(yīng)的調(diào)用棧,我們可以用下圖簡單的表示這個(gè)調(diào)用棧。

      每個(gè)方法在調(diào)用棧里都會(huì)有自己獨(dú)立的棧幀,每個(gè)棧幀里都有對(duì)應(yīng)方法需要的參數(shù)和返回地址。當(dāng)調(diào)用方法時(shí),會(huì)創(chuàng)建新的棧幀,并壓入調(diào)用棧;當(dāng)方法返回時(shí),對(duì)應(yīng)的棧幀就會(huì)被自動(dòng)彈出。

      我們可以這樣說:

      棧幀是在調(diào)用方法時(shí)創(chuàng)建,方法返回時(shí)“消亡”。

      局部變量存放在哪里?

      局部變量的作用域在方法內(nèi)部,當(dāng)方法執(zhí)行完,局部變量也就沒用了??梢赃@么說,方法返回時(shí),局部變量也就“消亡”了。此時(shí),我們會(huì)聯(lián)想到調(diào)用棧的棧幀。沒錯(cuò),

      局部變量就是存放在調(diào)用棧里的。

      此時(shí),我們可以將方法的調(diào)用棧用下圖表示。

      很多人都知道,局部變量會(huì)存放在棧里。

      如果一個(gè)變量需要跨越方法的邊界,就必須創(chuàng)建在堆里。

      調(diào)用棧與線程

      兩個(gè)線程就可以同時(shí)用不同的參數(shù)調(diào)用相同的方法。

      那么問題來了,調(diào)用棧和線程之間是什么關(guān)系呢?答案是:每個(gè)線程都有自己獨(dú)立的調(diào)用棧。

      我們可以使用下圖來簡單的表示這種關(guān)系。

      此時(shí),我們?cè)诳聪挛闹虚_頭的問題:

      Java方法內(nèi)部的局部變量是否存在并發(fā)問題?答案是不存在并發(fā)問題!因?yàn)槊總€(gè)線程都有自己的調(diào)用棧,局部變量保存在線程各自的調(diào)用棧里,不會(huì)共享,自然也就不存在并發(fā)問題。

      線程封閉

      【高并發(fā)】為什么局部變量是線程安全的?

      方法里的局部變量,因?yàn)椴粫?huì)和其他線程共享,所以不會(huì)存在并發(fā)問題。這種解決問題的技術(shù)也叫做線程封閉。官方的解釋為:僅在單線程內(nèi)訪問數(shù)據(jù)。由于不存在共享,所以即使不設(shè)置同步,也不會(huì)出現(xiàn)并發(fā)問題!

      好了,今天我們就到這兒吧,我是冰河,我們下期見?。?/p>

      Java JDK JVM 任務(wù)調(diào)度 多線程

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:Excel表格中如何計(jì)算日期所在的季度
      下一篇:以系統(tǒng)創(chuàng)新為基礎(chǔ),打造懂業(yè)務(wù)的SSD
      相關(guān)文章
      亚洲激情校园春色| 亚洲一级特黄特黄的大片| 亚洲欧洲国产成人精品| 亚洲成人激情在线| 中文字幕精品无码亚洲字| 日本系列1页亚洲系列| 亚洲乱色伦图片区小说| 亚洲国产成人久久三区| 亚洲AV综合色区无码二区爱AV| 亚洲精品视频在线观看视频| 亚洲视频精品在线| 亚洲精品一卡2卡3卡三卡四卡| 亚洲高清视频在线播放| 日韩亚洲Av人人夜夜澡人人爽| 91精品国产亚洲爽啪在线观看| 精品无码一区二区三区亚洲桃色| 国产AV无码专区亚洲AV男同| 精品亚洲综合在线第一区| 国产v亚洲v天堂无码网站| 亚洲国产成人久久精品动漫| 久久久亚洲欧洲日产国码aⅴ| 亚洲人成人网站在线观看| 亚洲成熟丰满熟妇高潮XXXXX| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 在线亚洲午夜理论AV大片| 亚洲中文字幕无码爆乳av中文 | 亚洲国产日韩在线人成下载| 亚洲人成7777| 亚洲AV一区二区三区四区| 老司机亚洲精品影院在线观看| 亚洲国产天堂久久久久久| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 亚洲网站在线播放| 亚洲avav天堂av在线网爱情| 亚洲女子高潮不断爆白浆| 国产AV无码专区亚洲AV琪琪| 狠狠亚洲婷婷综合色香五月排名| 亚洲爆乳无码专区| 亚洲噜噜噜噜噜影院在线播放| 亚洲综合一区国产精品| 亚洲av再在线观看|