一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 淺談Java多線程編程中Boolean常量的同步問題

淺談Java多線程編程中Boolean常量的同步問題

2020-01-12 14:27johnshen0708 JAVA教程

這篇文章主要介紹了淺談Java多線程編程中Boolean常量的同步問題,主要針對線程之間同步了不同的布爾對象的問題,需要的朋友可以參考下

在JAVA中通過synchronized語句可以實現多線程并發。使用同步代碼塊,JVM保證同一時間只有一個線程可以擁有某一對象的鎖。鎖機制實現了多個線程安全地對臨界資源進行訪問。
 
同步代碼寫法如下:
 
代碼1:

?
1
2
3
4
5
Object obj = new Object();
...
synchronized(obj) {
 //TODO: 訪問臨界資源
}

JAVA的多線程總是充滿陷阱,如果我們用Boolean作為被同步的對象,可能會出現以下兩種情況:
 
一. 以為對一個對象加鎖,實際同步的是不同對象。
 
代碼2:
 

?
1
2
3
4
5
6
7
8
9
10
11
private volatile Boolean isTrue = false;
 
publich void aMethod() {
 ...
 synchronized(isTrue) {
  isTrue = !isTrue;
  //TODO: 訪問臨界資源
  isTrue = !isTrue;
 }
 ...
}

 咋一看上面的代碼沒有問題,由于使用了synchronized(isTrue)同一時間只能有一個線程訪問臨界資源,但事實并不是這樣。因為false和true這兩個常量對應著兩個不同的對象。當isTrue產生變化時,很可能導致不同的線程同步了不同的對象。JAVA的自動裝箱會將false變為Boolean.FALSE,將true變為Boolean.TRUE(同時這也說明了此處若將false改為Boolean.FALSE其結果也是一樣的)。寫一個以上情況的測試代碼如下:
 
代碼3:
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class BooleanTest {
   
  private volatile Boolean isTrue = Boolean.FALSE; //此處用false也一樣
   
  public void aMethod() {
    for(int i=0;i<10;i++) {
      Thread t = new Thread() {
        public void run() {
          synchronized(isTrue) {
            isTrue = !isTrue;
            System.out.println(Thread.currentThread().getName() + " - isTrue=" + isTrue);
            try{
              Double ran = 1000 * Math.random();
              Thread.sleep(ran.intValue());
            }catch(InterruptedException e) {}
             
            if(!isTrue) System.out.println(Thread.currentThread().getName() + " - Oh, No!");
 
            isTrue = !isTrue;
          }
        }
      };
      t.start();
    }
  }
   
  public static void main(String... args) {
    BooleanTest bt = new BooleanTest();
    bt.aMethod();
  }
}

 運行以上代碼,不時的會看到 " - Oh, No!",表示不同的線程同時進入到synchronized代碼塊中。
 
二. 以為同步的是不同對象,實際是一個對象。
 
有時候我們可能希望在多個對象上進行同步,如果使用了Boolean作為被同步對象,很可能會導致本來應該沒有關系的兩個同步塊使用了相同對象的鎖。示例如下:
 
代碼4:
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private volatile Boolean aBoolean = Boolean.FALSE;
 
private volatile Boolean anotherBoolean = false;
 
public void aMethod() {
 ...
 synchronized(aBoolean) {
  //TODO: 訪問臨界資源1
 }
 ...
}
 
public void anotherMethod() {
 ...
 synchronized(anotherBoolean) {
  //TODO: 訪問臨界資源2
 }
 ...
}

 假設原本aMethod和anotherMethod分別會被兩組沒有關系的線程調用。但是由于Boolean.FALSE和false指向的是同一個對象,可能導致對臨界資源2的訪問被臨界資源1阻塞了(反之亦然)。
 
以上兩種情況說明,在使用同步塊時,盡量不用使用Boolean對象作為被同步對象,不然可能會出現意想不到的問題,或者對以后的代碼修改造成陷阱。
 
從此也可以看出,任何對常量的同步都是有風險的。如果一定要對 Boolean 進行同步,一定要用 new 操作符來創建 Boolean 對象。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 挑色视频| 亚洲高清在线天堂精品 | 9久re热视频这里只有精品 | 国色天香社区视频免费高清在线观看 | 人人澡 人人澡碰人人看软件 | 国产亚洲精品一区二区在线播放 | 全彩孕交漫画福利啪啪吧 | 性夜影院爽黄A爽免费动漫 性色欲情网站IWWW九文堂 | 水岛津实在线 | 日本红怡院亚洲红怡院最新 | 色综合视频一区二区三区 | 国产做a爰片久久毛片 | 高清视频在线观看+免费 | 国产人妖xxxxx免费看 | 国产免费成人在线视频 | 四虎成人免费观看在线网址 | 我和老丈洗澡同性 | 大肥女zzz00o | 亚洲www美色 | 日韩 欧美 国产 亚洲 中文 | 女人被爽到呻吟娇喘的视频动态图 | 久久精品免视看国产 | 欧美日韩一二三区免费视频观看 | 性夜夜春夜夜爽AA片A | 嫩草影院永久入口在线观看 | 国产精品免费久久久久影院 | 99久久精品国产一区二区 | 50度灰破解版v5.7.0 | 四虎成人免费观看在线网址 | 天堂在线观看中文字幕 | 91在线永久 | 40分钟在线观看免费 | 欧美高清免费一级在线 | 涩涩屋在线观看 | 亚洲国产99在线精品一区69堂 | 亚洲一区二区三区深夜天堂 | 精品国产乱码久久久久久人妻 | 国产一卡2卡3卡四卡国色天香 | 亚洲黄色大片 | 乳色吐息讲的是什么 | 久久91精品国产91久 |