<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## Java專題十三(3):內存模型、volatile、ThreadLocal [TOC] ### JVM內存模型 ![](https://img.kancloud.cn/73/a0/73a0393e9246be62b1885c1123ae4af8_486x435.png) 在JVM中主要分為Thread Stack和Heap,每一個線程都會復制一份局部變量到自己的線程棧中,所以一個線程對局部變量的改變對另一個線程是不可見的 - 線程棧(Thread Stack):存儲了所有方法內部的局部變量(包括基本數據類型和對對象的引用) - 堆區(Heap):存儲了所有對象,成員變量(包括基本數據類型,且和所屬對象一同存儲在Heap中) ### 物理內存模型 ![](https://img.kancloud.cn/52/6a/526af1d03f57b6fc3d8b42a7aa800f20_452x398.png) 物理內存模型包括3層,`CPU`、`CPU Cache Memory`、`Main Memory`,操作數據的速度排序:`CPU` > `CPU Cache Memory` > `Main Memory`,這里的`Main Memory`就是我們所說的內存。 當一個線程修改共享數據時,需要先從`Main Memory`讀取共享數據到`CPU Cache Memory`時,當然只要它沒有寫回到`Main Memory`,對共享數據的改變就不會讓其它線程知道,即對其它線程時不可見的 ### volatile關鍵字 使用volatile關鍵字保證了對其它線程對變量寫的可見性,具體表現如下 - 對volatile變量的每一次讀取都是從`Main Memory`中讀取的,而不是從`CPU Cache Memory`中讀取的 - 對volatile變量的修改會馬上寫回到`Main Memory`中 如:`java.util.Thread`中聲明的成員變量`private volatile String name;` ### ThreadLocal變量 `java.lang.ThreadLocal`是java提供的一個類,每個線程對`ThreadLocal`變量的讀寫操作(get和set方法)都保存著變量的一個副本,因此相對于其它線程來說是隔離互不影響的,但無法完成共享變量的操作,也就不存在所謂的線程安全問題 | 方法 | 壽命 | | --- | --- | | `void set(T value)`| 設置值 | | ` T get()` | 獲取值 | | `T initialValue()`| 初始化值 | | `void remove()` | 移除值 | | `static <S> ThreadLocal<S> ` <br>` withInitial(Supplier<? extends S> supplier)` | 靜態方法,初始化值 | 使用方法如下: ~~~ ThreadLocal<String> threadLocal = new ThreadLocal<String>(){ @Override protected String initialValue() { return ""; } }; // can use with follow method to initial value ThreadLocal<String> threadLocal1 = ThreadLocal.withInitial(new Supplier<String>() { @Override public String get() { return ""; } }); threadLocal.set("java"); threadLocal.get(); // "java" threadLocal.remove(); // remove "java" threadLocal.get(); // with initial value: "" ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看