簡體   English   中英

Java不確定嗎?

[英]Java not deterministic?

我在Java中編寫了一些捕食者 - 獵物模擬。 即使規則非常復雜並且最終處於混亂系統中,所使用的技術也很簡單:

  • 關於基本數據類型的算術和決策
  • 沒有外部庫
  • 沒有包括外部系統
  • 沒有並發發生
  • 不使用當前時間或日期

所以我認為在用相同的參數初始化系統時它應該輸出相同的結果,但它沒有,我想知道為什么。

關於這一點的一些想法:我的應用程序使用Random s,但是對於該測試,我使用給定值初始化它們,因此在我的理解中,它們應該為每次運行創建相同順序的相同輸出。

我正在迭代Set s,我知道沒有定義迭代Set的順序。 但是我沒有看到任何理由為什么以相同的值填充相同順序的Set在多次運行中應該表現不同。 可以?

我正在使用很多float 1 + 1 = 1.9999999999725的數據類型總是讓我懷疑,但即使他們的行為對我來說很奇怪,也應該總是一樣奇怪。 不是嗎?

垃圾收集不是確定性的,但只要我不依賴於析構函數,我就應該是安全的。

如上所述,根據實際使用時間,沒有並發性和數據類型。

我不能在一個簡單的例子中重現這種行為。 但是通過我的代碼,我看不到任何可能無法預測的事情。 那么我上面的任何假設都是錯誤的嗎? 我有什么想法可以錯過嗎?

這是驗證我的假設的測試:

public static void main(String[] args) {
    Random r = new Random(1);
    Set<Float> s = new HashSet<Float>();
    for (int i = 0; i < 1000000; i++) {
        s.add(r.nextFloat());
    }

    float ret = 1;
    int cnt = 0;
    for (Float f : s) {
        float multiply = 0.3f;
        if (cnt++ % 2 == 0) {
            multiply = 0.7f;
        }
        float f2 = (f * multiply);
        ret += f2;
    }

    System.out.println(ret);
}

它對我來說總是在242455.25。

您可以用Java編寫確定性程序。 你只需要消除非確定性的可能來源。

如果沒有看到你的實際代碼,那么很難知道什么可能導致非決定論,以及這種決定論的具體證據。

有許多庫方法可能是非確定性行為的來源......取決於您如何使用它們。

例如, Object.hashcode()返回的值(第一次在實例上調用)是非確定性的。 並且滲透到任何使用散列的庫。 它肯定會影響迭代它們時返回HashSetHashMap元素的順序...如果元素類不覆蓋hashcode()

隨機數生成器可能是也可能不是確定性的。 如果它們是偽隨機的並且用固定種子初始化,則每個生成的數字序列將是確定性的。

浮點運算應該是確定性的。 對於算術表達式的任何(固定)輸入集,結果應始終相同。 (我不確定浮點運算的確定性是否由JLS保證,但是如果它在實踐中發生的話會很奇怪。就像......你在破壞的硬件上運行。)


關注 ...關於strictfp和非確定性。

根據JLS 15.4

“在一個非FP嚴格的表達式中,為實現使用擴展指數范圍來表示中間結果的一些余地被授予;大致說來,凈效應是計算可能在以下情況下產生”正確答案“獨占使用浮點值設置或雙值設置可能會導致上溢或下溢。“

這並不能說明實現在非FP嚴格表達式中有多少 “余地”。 但是,我認為這種余地不會擴展到允許非確定性行為。 我曾經認為特定平台上的JIT編譯器總是會為同一個表達式生成等效的本機代碼,並且該代碼將是確定性的。 (我看不出任何非確定性的原因......除非硬件本身具有非確定性浮點。)非確定性的另一個可能來源可能是JIT編譯和解釋代碼的行為可能不同。 但坦率地說,我認為允許這種情況發生是“堅果”......我想我們已經聽說過了。

因此,雖然非FP嚴格的表達評估在理論上可能是非確定性的,但我認為我們應該對此進行折扣......除非有明確證據表明它在實踐中發生。

(請注意,我說的是真正的非決定論,而不是平台差異。)

我正在迭代通過集合,我知道迭代的集合的順序沒有被定義。 但是我沒有看到為什么以相同的值填充相同順序的Set在多次運行中應該表現不同的原因。 可以?

它可以。 該實現可以自由使用,例如,對象在內存中的位置作為底層哈希表的鍵。 這取決於垃圾收集何時運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM