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

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

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

服務器之家 - 編程語言 - JAVA教程 - 在Java內存模型中測試并發程序代碼

在Java內存模型中測試并發程序代碼

2019-12-25 13:46goldensun JAVA教程

這篇文章主要介紹了在Java內存模型中測試并發程序代碼,輔以文中所提到的JavaScript庫JCStress進行,需要的朋友可以參考下

讓我們來看看這段代碼:
 

?
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
32
33
34
35
36
37
38
39
import java.util.BitSet;
import java.util.concurrent.CountDownLatch;
 
public class AnExample {
 
  public static void main(String[] args) throws Exception {
    BitSet bs = new BitSet();
    CountDownLatch latch = new CountDownLatch(1);
    Thread t1 = new Thread(new Runnable() {
      public void run() {
        try {
          latch.await();
          Thread.sleep(1000);
        } catch (Exception ex) {
        }
        bs.set(1);
      }
    });
    Thread t2 = new Thread(new Runnable() {
      public void run() {
        try {
          latch.await();
          Thread.sleep(1000);
        } catch (Exception e) {
        }
        bs.set(2);
      }
    });
 
    t1.start();
    t2.start();
    latch.countDown();
    t1.join();
    t2.join();
   // crucial part here:
    System.out.println(bs.get(1));
    System.out.println(bs.get(2));
  }
}

問題來了,這段代碼輸出的結果是什么呢?它究竟能輸出什么結果,上面的程序即使在崩潰的JVM上,仍然允許打印輸出什么結果呢?

讓我們來看看這個程序做了什么:

  •     初始化了一個BitSet對象
  •     兩個線程并行運行,分別對第一和第二位的字段值設置為true
  •     我們嘗試讓這兩個線程同時運行。
  •     讀取BitSet對象的值,然后輸出結果。

接下來,我們需要構造一些測試用例來檢查這些行為。顯然,其中一個只能運行該例子,然后觀察結果,回答上面的問題,可是,回答第二個關于允許輸出的結果,需要些技巧。

熟能生巧

幸運的是,我們可以使用工具。 JCStress 就是一個為了解決這類問題而產生的測試工具。

我們可以很容易地將我們的test case寫成JCStress可以識別的形式。事實上, 它已經為我們準備好了多種可能情況下的接口。我們需要一個例子,在這個例子中,2個線程并發地執行,執行的結果表示為2個布爾值。

我們使用一個Actor2_Arbiter1_Test<BitSet, BooleanResult2>接口, 它將為我們的2個線程提供一些方法塊和一個轉換方法,這個轉換方法將表示BitSet狀態的結果轉換成一對布爾值。我們需要找個 Java 8 JVM 來運行它, 但是現在這已經不是什么問題了.

看下面的實現. 是不是特別簡潔?
 

?
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
public class AnExampleTest implements
      Actor2_Arbiter1_Test<BitSet, BooleanResult2> {
 
 @Override
 public void actor1(BitSet s, BooleanResult2 r) {
  s.set(1);
 }
 
 @Override
 public void actor2(BitSet s, BooleanResult2 r) {
  s.set(2);
 }
 
 @Override
 public void arbiter1(BitSet s, BooleanResult2 r) {
  r.r1 = s.get(1);
  r.r2 = s.get(2);
 }
 
 @Override
 public BitSet newState() {
  return new BitSet();
 }
 
 @Override
 public BooleanResult2 newResult() {
  return new BooleanResult2();
 }
}


現在在運行這個測試的時候,控制會去嘗試各種花樣以求獲取驅動這些動作的因素的所有可能組合: 并行的或者非并行的, 有和無負載檢測的, 還有一行中進行許多許多次, 因此所有可能的結果都會被記錄到.

當你想知道你的并行代碼是如何運作的時候,這是比靠你自己去挖空心思想出所有細節更勝一籌的辦法.

此外,為了能利用到JCStress 約束帶來的全面性的便利,我們需要給它提供一個對可能結果的解釋. 要那樣做的話我們就需要使用如下所示的一個簡單的XML文件.

?
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
32
33
<test name="org.openjdk.jcstress.tests.custom.AnExampleTest">
 <contributed-by>Oleg Shelajev</contributed-by>
 <description>
  Tests if BitSet works well without synchronization.
 </description>
 <case>
  <match>[true, true]</match>
  <expect>ACCEPTABLE</expect>
  <description>
   Seeing all updates intact.
  </description>
 </case>
 <case>
  <match>[true, false]</match>
  <expect>ACCEPTABLE_INTERESTING</expect>
  <description>
   T2 overwrites T1 result.
  </description>
 </case>
 <case>
  <match>[false, true]</match>
  <expect>ACCEPTABLE_INTERESTING</expect>
  <description>
   T1 overwrites T2 result.
  </description>
 </case>
 <unmatched>
  <expect>FORBIDDEN</expect>
  <description>
   All other cases are unexpected.
  </description>
 </unmatched>
</test>

現在,我們已經準備好讓這頭野獸開始咆哮了. 通過使用下面的命令行運行測試.

?
1
java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-RestrictContended -jar tests-custom/target/jcstress.jar -t=".*AnExampleTest"

而我們所得到的結果是一份優雅的報告.

在Java內存模型中測試并發程序代碼

現在很清楚的是,我們不僅可以得到預期的結果,即兩個線程都已經設置了它們的位,也遇到了一個競爭條件,一個線程將覆蓋另一個線程的結果。

即使你看到發生了這種事情,也一定要有“山人自有妙計”的淡定心態,不是嗎?

順便說一下,如果你在思考如何修改這個代碼,答案是仔細閱讀 Javadoc 中的 BitSet 類,并意識到那并非是線程安全的,需要外部同步。這可以很容易地通過增加同步塊相關設定值來實現。
 

?
1
2
3
synchronized (bs) {
 bs.set(1);
}

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费观看无人区完整版 | 精品破处 | 成人午夜视频一区二区国语 | 国产一区二区三区四区波多野结衣 | 精品国产一区二区三区久 | 日韩精选| 思思久久精品在热线热 | 99手机在线视频 | 欧美精品三区 | 国产日韩欧美不卡www | 欧美18-19| 天美传媒在线视频 | 大学生按摩黄a级中文片 | 亚洲福利一区二区精品秒拍 | 火影小南被爆羞羞网站 | 欧美成人福利 | 国产日产韩产麻豆1区 | 99在线在线视频免费视频观看 | 日韩在线成人 | 日韩 欧美 国产 亚洲 中文 | 无码11久岁箩筣 | 潘甜甜在线观看 | 2015台湾永久免费平台 | 无耻之徒第十一季在线观看 | 精品国产自在现线拍国语 | 国产成人精品免费久久久久 | 欧美a级在线 | 2022天天干 | 91久久青青青国产免费 | 911精品国产亚洲日本美国韩国 | 精油按摩日本 | 亚洲国产精品嫩草影院久久 | 国内精品久久久久影院中国 | 国产性做久久久久久 | 国产免费午夜 | 北海市副市长黄江老公 | 三极黄色 | 好姑娘在线观看完整版免费 | 日本色播| 秋葵丝瓜茄子草莓榴莲樱桃 | 国产ab |