国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

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

2019-11-26 14:54:41
字體:
來源:轉載
供稿:網友

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

Object obj = new Object(); ... synchronized(obj) {  //TODO: 訪問臨界資源 } 

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

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:
 

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:
 

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 對象。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武川县| 阿鲁科尔沁旗| 疏附县| 潮安县| 沅江市| 井研县| 沅江市| 曲阳县| 太湖县| 全州县| 文昌市| 来宾市| 小金县| 五指山市| 民县| 本溪| 辉县市| 肃南| 铜陵市| 娄烦县| 瑞昌市| 河东区| 庆云县| 西昌市| 喀喇沁旗| 三门县| 浦北县| 津南区| 乌拉特后旗| 休宁县| 宿松县| 景东| 页游| 香港| 盐山县| 黄山市| 上栗县| 泰和县| 宁化县| 渝北区| 黔南|