最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在Java內(nèi)存模型中測試并發(fā)程序代碼

 更新時間:2015年07月10日 11:19:48   投稿:goldensun  
這篇文章主要介紹了在Java內(nèi)存模型中測試并發(fā)程序代碼,輔以文中所提到的JavaScript庫JCStress進行,需要的朋友可以參考下

讓我們來看看這段代碼:
 

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));
  }
}

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

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

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

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

熟能生巧

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

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

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

看下面的實現(xiàn). 是不是特別簡潔?
 

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();
 }
}


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

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

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

 <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>

現(xiàn)在,我們已經(jīng)準(zhǔn)備好讓這頭野獸開始咆哮了. 通過使用下面的命令行運行測試.

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

而我們所得到的結(jié)果是一份優(yōu)雅的報告.

2015710111243724.png (955×280)

現(xiàn)在很清楚的是,我們不僅可以得到預(yù)期的結(jié)果,即兩個線程都已經(jīng)設(shè)置了它們的位,也遇到了一個競爭條件,一個線程將覆蓋另一個線程的結(jié)果。

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

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

synchronized (bs) {
 bs.set(1);
}

相關(guān)文章

  • SpringBoot配置的加載流程詳細分析

    SpringBoot配置的加載流程詳細分析

    了解內(nèi)部原理是為了幫助我們做擴展,同時也是驗證了一個人的學(xué)習(xí)能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會的,這篇文章主要介紹了SpringBoot配置的加載流程
    2023-01-01
  • mybatis關(guān)系映射之一對多和多對一

    mybatis關(guān)系映射之一對多和多對一

    今天小編就為大家分享一篇關(guān)于mybatis關(guān)系映射之一對多和多對一,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 基于Java實現(xiàn)ssh命令登錄主機執(zhí)行shell命令過程解析

    基于Java實現(xiàn)ssh命令登錄主機執(zhí)行shell命令過程解析

    這篇文章主要介紹了基于Java實現(xiàn)ssh命令登錄主機執(zhí)行shell命令過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • spring kafka框架中@KafkaListener 注解解讀和使用案例

    spring kafka框架中@KafkaListener 注解解讀和使用案例

    Kafka 目前主要作為一個分布式的發(fā)布訂閱式的消息系統(tǒng)使用,也是目前最流行的消息隊列系統(tǒng)之一,這篇文章主要介紹了kafka @KafkaListener 注解解讀,需要的朋友可以參考下
    2023-02-02
  • java如何根據(jù)提供word模板導(dǎo)出word文檔詳解

    java如何根據(jù)提供word模板導(dǎo)出word文檔詳解

    在日常的開發(fā)工作中,我們時常會遇到導(dǎo)出Word文檔報表的需求,比如公司的財務(wù)報表、醫(yī)院的患者統(tǒng)計報表、電商平臺的銷售報表等等,這篇文章主要給大家介紹了關(guān)于java如何根據(jù)提供word模板導(dǎo)出word文檔的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • 解析SpringSecurity自定義登錄驗證成功與失敗的結(jié)果處理問題

    解析SpringSecurity自定義登錄驗證成功與失敗的結(jié)果處理問題

    這篇文章主要介紹了SpringSecurity系列之自定義登錄驗證成功與失敗的結(jié)果處理問題,本文通過實例給大家講解的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • 學(xué)習(xí)Java的static與final關(guān)鍵字

    學(xué)習(xí)Java的static與final關(guān)鍵字

    本篇文章給大家詳細分析了Java的static與final關(guān)鍵字知識點以及相關(guān)代碼分享,有需要的讀者跟著學(xué)習(xí)下吧。
    2018-03-03
  • 淺談Java生成唯一標(biāo)識碼的三種方式

    淺談Java生成唯一標(biāo)識碼的三種方式

    我們經(jīng)常會遇到這樣的場景,需要生成一個唯一的序列號來表明某一個數(shù)據(jù)的唯一性,本文主要介紹了淺談Java生成唯一標(biāo)識碼的三種方式,感興趣的可以來了解一下
    2022-01-01
  • SpringBoot實現(xiàn)Server-Sent Events(SSE)的使用完整指南

    SpringBoot實現(xiàn)Server-Sent Events(SSE)的使用完整指南

    使用SpringBoot實現(xiàn)Server-Sent Events(SSE)可以有效處理實時數(shù)據(jù)推送需求,具有單向通信、輕量級和高實時性等優(yōu)勢,本文詳細介紹了在SpringBoot中創(chuàng)建SSE端點的步驟,并通過代碼示例展示了客戶端如何接收數(shù)據(jù),適用于實時通知、數(shù)據(jù)展示和在線聊天等場景
    2024-09-09
  • SpringBoot整合Drools規(guī)則引擎動態(tài)生成業(yè)務(wù)規(guī)則的實現(xiàn)

    SpringBoot整合Drools規(guī)則引擎動態(tài)生成業(yè)務(wù)規(guī)則的實現(xiàn)

    本文主要介紹了SpringBoot整合Drools規(guī)則引擎動態(tài)生成業(yè)務(wù)規(guī)則的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12

最新評論

五指山市| 中方县| 深圳市| 呼和浩特市| 马边| 昌江| 南郑县| 铜梁县| 永新县| 蒙山县| 丰城市| 吉安县| 屯昌县| 廊坊市| 大庆市| 济南市| 开封县| 海淀区| 南京市| 浦江县| 柳林县| 长乐市| 青浦区| 清苑县| 句容市| 绩溪县| 托克托县| 榆树市| 收藏| 绥芬河市| 辰溪县| 西畴县| 华坪县| 南乐县| 资阳市| 平江县| 新田县| 萨迦县| 焦作市| 万山特区| 永修县|