<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java并發(fā)編程:什么是線程安全性--基礎知識

          共 2402字,需瀏覽 5分鐘

           ·

          2021-08-28 14:56

          ??前言

          來自我對一位我所崇拜的大佬文章的評論:

          我:“喝罷黃河之水天上來,酒醒楊柳殘月且偷歡,唱罷笑傲江湖祭滄海,雁渡寒潭有幾只回還”

          大佬:“年少正恰,縱碼飛騁,略江山華月,有幾人隨傅虎踞龍盤。”


          ??進入正題

          線程或者鎖在并發(fā)編程中的作用,類似于鉚釘和工字梁在土木工程中的作用。要建筑一座堅固的橋梁,必須正確地使用大量的鉚釘和工字梁。同理,在構建穩(wěn)健的并發(fā)程序時,必須正確地使用線程和鎖。但這些終歸只是一些機制。要編寫線程安全的代碼,其核心在于要對狀態(tài)訪問操作進行管理,特別是對共享(Shared)和可變的(Mutable)狀態(tài)的訪問。

          • 對象的狀態(tài):指存儲在狀態(tài)變量中的數(shù)據(jù),當然也可能包含其他依賴對象的域。

            • 例如,某個 HashMap 的狀態(tài)不僅存儲在 HashMap 對象本身,還存儲在許多 Map.Entry 對象中。在對象的狀態(tài)中包含了任何可能影響其外部可見行為的數(shù)據(jù)。

          • 共享Shared:共享意味著變量可以有多個線程同時訪問。

          • 可變Mutable:意味著變量的值在其生命周期內(nèi)可以發(fā)生變化。

          注釋:討論線程安全性,更應該側(cè)重于如何防止在數(shù)據(jù)上發(fā)生不受控的并發(fā)訪問。一個對象是否需要是線程安全的,取決于他是否被多個線程訪問。(指的是在程序中訪問對象的方式,而不是對象要實現(xiàn)的功能)

          當多個線程訪問某個狀態(tài)變量并且其中有一個線程執(zhí)行寫入操作時,必須采用同步機制來協(xié)同這些線程對變量的訪問。

          • 關鍵字 synchronized:提供獨占的加鎖方式。

          • voatile 類型變量:同步應該要包括的還有,顯式鎖(Explicit Lock)以及原子變量。

          如果忽略了某一個同步的機制,可能會造成的后果,當多個線程訪問同一個可變的狀態(tài)變量時沒有使用合適的同步,程序就會出錯,修復:

          • 不在線程之間共享該狀態(tài)變量

          • 將狀態(tài)變量修改為不可變的變量

          • 在訪問狀態(tài)變量時使用同步

          注釋:當設計線程安全的類時,良好的面向?qū)ο蠹夹g、不可修改性,以及明晰的不變形規(guī)范都能起到一定的幫助作用。

          在編寫并發(fā)應用程序時,一種正確的編程方法就是:首先代碼正確運行,然后再提高代碼速度。即便如此,最好也只是當性能測試結(jié)果和應用需求告訴你必須提高性能,以及測量結(jié)果表明這種優(yōu)化在實際環(huán)境中確實能帶來性能提升時,才進行優(yōu)化。


          ?? 什么是線程安全性

          我們都知道:定義越正式,就越復雜,不僅很難提供由實際意義的指導建議,而且也很難從直觀上去理解。網(wǎng)上的“定義”有很多,比如:

          • ······ 可以在多個線程中調(diào)用,并且在線程之間不會出現(xiàn)錯誤的交互。

          • ······ 可以同時被多個線程調(diào)用,而調(diào)用者無須執(zhí)行額外的動作。

          也難怪我們會對線程安全性感到困惑,因為聽起來就想“如果某個類可以在多個線程中安全的使用,那么它就是一個線程安全的類?!彪m然不存在很多爭議,但是有什么實際的意義和幫助么。

          “安全”的含義是什么:

          • 在線程安全的定義中,最核心的概念就是正確性。

          • 正確的含義是——某個類的行為與其規(guī)范完全一致

          我將單線程的正確性近似定義為“所見即所知”,在對“正確性”給出了一個較為清晰的定以后,就可以定義線程安全性:

          • 當多個線程訪問某個類時,這個類始終都能表現(xiàn)出正確的行為,那么就稱這個類是線程安全的。

          • 當多個線程訪問某個類時,不關于刑事環(huán)境采用何種調(diào)度方式或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個類都能表現(xiàn)出正確的行為,那么就稱呼這個類是線程安全的。

          • 由于單線程程序也可以看成多線程程序,若某個類在單線程環(huán)境下都不是正確的,那么它肯定不會是線程安全(也就是說一個程序首先要能正常的工作保證正確性)。


          ?簡單的示例

          通常,線程安全性的需求并非來源于對縣城的直接使用,而是使用像 Servlet 這樣的框架(還有很多)。

          一個基于 Servlet 的因數(shù)分解服務,并逐步擴展功能,并確保它的線程安全性。

          一個無狀態(tài)的 Servlet

          @ThreadSafe
          public class StatelessFactorizer implements Servlet {
          public void service(ServletRequest req,ServletResponse resp) {
          BigInteger i = extractFromRequest(req);
          BigInteger[] factors = factor(i);
          encodeIntoResponse(resp,factors);
          }
          }
          復制代碼

          與大多數(shù) Servlet 相同,StatelessFactorizer 是無狀態(tài)的,它既不包含任何域,也不包含任何對其他類中域的引用。計算過程中的臨時狀態(tài)僅存在于線程棧上的局部變量中,并且只能由正在執(zhí)行的線程訪問。訪問 StatelessFactorizer 的線程不會影響另外一個訪問同一個 StatelessFactorizer 的線程的計算結(jié)果 ,因為這兩個線程并沒有共享狀態(tài),就好像他們都在訪問不同的實例。由于線程訪問無狀態(tài)對象的行為并不會影響其他線程中操作的正確性,因此無狀態(tài)對象是線程安全的。

          • 無狀態(tài)對象一定是線程安全的。

          • 大多數(shù) Servlet 都是無狀態(tài)的,從而極大地降低了在實現(xiàn) Servlet 線程安全性時的復雜性。只有當 Servlet 在處理請求時需要保存一些信息線程安全性才會成為一個問題。


          作者:Sunny_Chen
          鏈接:https://juejin.cn/post/6999423430462275592
          來源:掘金
          著作權歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權,非商業(yè)轉(zhuǎn)載請注明出處。



          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  少妇一级婬片日本 | 久久久久亚洲AV成人片乱码 | 国产字幕中文 | 日韩毛片大全 | 亚洲无码高清在线 |