2012-03-06 42 views
0

的在實施例下面無法模擬使用揮發性字段修飾符

private Integer a = 10; 
    private Integer c = -10; 
    private int b = -10; 

    public void acquire(){ 
     synchronized(a){ 
      print("acquire()"); 
      try{      
       b = -12; 
       //Thread.sleep(5000); 
       a.wait(5000); 
       print("acquire : "+b); 
       print("I have awoken"); 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 
     print("Leaving acquire()"); 
    } 


    public void modify(int n){ 
     print("Entered in modfy"); 
     synchronized(a){ 
      try{      
       b = -15; 
       //a.wait(5000); 
       Thread.sleep(5000); 
       print("modfy : "+b); 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 
    } 

線程A在調用獲取(),線程B是調用修改()。

由一個線程更改的b的值對另一個線程可見。

  1. 線程A:b = -12;並等待
  2. 線程B:b = -15;打印b;退出
  3. 線程A:打印b ie -15的新值。

我如何可以模擬需要的揮發性與上面的例子則在上面的例子中使用volatile

+0

這是家庭作業的傢伙? – Gray 2012-03-06 04:52:05

+0

此主題中的以前的問題是:http://stackoverflow.com/questions/9571982/waitn-is-acting-different-each-time-i-change-the-position-of-synchronized-keyw/9572023和http: //stackoverflow.com/questions/9577913/where-to-call-wait – Gray 2012-03-06 04:52:48

+2

即使你沒有兩面看過馬路,你也不能保證會被汽車撞到。沒有保證失敗的方法,規則不會以這種方式工作。 (就像沒有看到*保證*就沒有辦法過馬路,你會被汽車撞到。) – 2012-03-06 05:00:47

回答

0

我這裏有

http://vanillajava.blogspot.com/2012/01/demonstrating-when-volatile-is-required.html

一個例子,你可能會發現存在哪些問題;

  • 雖然volatile提供了一些內存一致性保證,不使用揮發性保證你會看到一個問題。
  • 在Sun/Oracle/OpenJDK JVM出現問題之前,代碼已經過優化,即運行10,000次之後。
  • 通常存在一個微妙的競爭條件,即使是微小的事情也可能會發生變化,這可能意味着您沒有看到問題。
0

如果你只是想模擬volatile需要簡單地做到這一點:

volatile int x = 10; 
public void acquire() 
{ 
    x = 15; 
    print("acquire()"); 
} 

public void modify(int n) 
{ 
    print("Entered in modfy"); 
    x = -15; 
} 

//Let threadA call acquire() and threadB call modify()Then print x and see (there should not be any race conditions) 

如果你想使更多的樂趣,添加一些更多的線程和方法,並嘗試訪問x

+0

如果這麼簡單,也許你可以提供一個完整的例子。 ;) – 2012-03-06 08:47:31

+0

@PeterLawrey:我在這裏感覺到諷刺:)。在使用套接字編寫多線程Java程序時,我使用了volatile。我會有一個通用的令牌('volatile int array'),其中多個線程更新。我認爲這可能是相同的。如果不是,請詳細說明。 – noMAD 2012-03-06 18:12:04

+0

我懷疑它不像你所建議的那麼簡單,但我很高興被證明是錯誤的。 – 2012-03-06 20:27:04

0

根據「Concurrency in Practice - Book」,volatile應該只用於flags變量的類型(這是布爾值)。 揮發性應該用在新狀態不依賴於舊狀態變量的情況下。

volatile boolean flag = true;

while(flag){ .. // do something;

}

當標記變量可以由其它線程進行修改,原來的線程將被通知,因爲該標誌被加標籤的揮發性。否則,循環可能會永遠持續下去。