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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

变量的线程安全分析

發布時間:2023/12/29 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 变量的线程安全分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

成員變量和靜態變量是否線程安全?

  • 如果它們沒有共享,則線程安全。
  • 如果它們被共享了,根據他們的狀態是否能夠改變,又分兩種情況
    • 只是讀操作,則線程安全
    • 如果有讀寫操作,則這段代碼是臨界區,需要考慮線程安全

局部變量是否線程安全?

局部變量是線程安全的

但局部變量引用的對象則未必

如果該對象沒有逃離方法的作用范圍,它是線程安全的

如果該對象逃離方法的作用范圍,需要考慮線程安全

局部變量線程安全分析

想一想,這段代碼被多個線程訪問,它是線程安全的嗎?

public static void test1() {int i = 10;i++;}

i++不是一個原子操作,它是線程不安全的,也許會從這方面去考慮,但實際上這段代碼是線程安全的。

反編譯為字節碼后,一共有4行指令,第一行指令準備了一個常量10 第二行指令把10賦值給i,第三行指令的時候在局部變量i上進行自增1的操作,第四行指令就return了。

從這幾行代碼來看, 發現局部變量的i++操作和靜態變量的i++的字節碼指令是稍有不同的。incc這個指令只有一行就完成了++操作,就不會像靜態變量的i++一樣指令被分成了多個,影響原子性。

而每個線程調用此方法時,局部變量i會在每個線程的棧幀內存中被創建多份,因此不存在共享。

還記得局部變量是線程私有的嗎?

線程分別在自己的棧幀中完成了i++操作,互不影響。

局部變量引用

在循環里調用method1,method2,method3,讓mothod2在list里加一個元素,再讓method3去remove這個元素。

調用執行后很快的就報錯了。

public class TestThreadSafe {static final int THREAD_NUMBER = 2;static final int LOOP_NUMBER = 200;public static void main(String[] args) {ThreadSafeSubClass test = new ThreadSafeSubClass();for (int i = 0; i < THREAD_NUMBER; i++) {new Thread(() -> {test.method1(LOOP_NUMBER);}, "Thread" + (i+1)).start();}} } class ThreadUnsafe {ArrayList<String> list = new ArrayList<>();public void method1(int loopNumber) {for (int i = 0; i < loopNumber; i++) {method2();method3();}}private void method2() {list.add("1");}private void method3() {list.remove(0);} } }

因為method2和methoed3都調用的同一個對象中的list成員變量。

?進行一些小改動,讓它變得線程安全,讓list成為方法內的局部變量。

class ThreadSafe {public final void method1(int loopNumber) {ArrayList<String> list = new ArrayList<>();for (int i = 0; i < loopNumber; i++) {method2(list);method3(list);}}public void method2(ArrayList<String> list) {list.add("1");}private void method3(ArrayList<String> list) {System.out.println(1);list.remove(0);} }

分析這段代碼為什么變成了線程安全的?

  • list是局部變量,每個線程調用時會創建其不同的實例,沒有共享。
  • 而method2的參數是method1中傳遞過來的,與method1引用同一個對象。
  • method3的參數分析與method2相同。

?

總結

以上是生活随笔為你收集整理的变量的线程安全分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。