程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 淺談Java多線程編程中Boolean常量的同步成績

淺談Java多線程編程中Boolean常量的同步成績

編輯:關於JAVA

淺談Java多線程編程中Boolean常量的同步成績。本站提示廣大學習愛好者:(淺談Java多線程編程中Boolean常量的同步成績)文章只能為提供參考,不一定能成為您想要的結果。以下是淺談Java多線程編程中Boolean常量的同步成績正文


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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved