天天看點

Java記憶體模型FAQ(二到六)原文Do other languages, like C++, have a memory model?原文What is JSR 133 about?原文What is meant by reordering?原文What was wrong with the old memory model?原文What do you mean by “incorrectly synchronized”?

Java記憶體模型FAQ(二) 其他語言,像C++,也有記憶體模型嗎?

原文:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html 第二章

譯者:Alex

大部分其他的語言,像C和C++,都沒有被設計成直接支援多線程。這些語言對于發生在編譯器和處理器平台架構的重排序行為的保護機制會嚴重的依賴于程式中所使用的線程庫(例如pthreads),編譯器,以及代碼所運作的平台所提供的保障。

原文

Do other languages, like C++, have a memory model?

Most other programming languages, such as C and C++, were not designed with direct support for multithreading. The protections that these languages offer against the kinds of reorderings that take place in compilers and architectures are heavily dependent on the guarantees provided by the threading libraries used (such as pthreads), the compiler used, and the platform on which the code is run.

原創文章,轉載請注明: 轉載自并發程式設計網 – ifeve.com本文連結位址: Java記憶體模型FAQ(二) 其他語言,像C++,也有記憶體模型嗎?

Java記憶體模型FAQ(三)JSR133是什麼?

原文:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html 第三章

譯者:Alex

從1997年以來,人們不斷發現Java語言規範的17章定義的Java記憶體模型中的一些嚴重的缺陷。這些缺陷會導緻一些使人迷惑的行為(例如final字段會被觀察到值的改變)和破壞編譯器常見的優化能力。

Java記憶體模型是一個雄心勃勃的計劃,它是程式設計語言規範第一次嘗試合并一個能夠在各種處理器架構中為并發提供一緻語義的記憶體模型。不過,定義一個既一緻又直覺的記憶體模型遠比想象要更難。JSR133為Java語言定義了一個新的記憶體模型,它修複了早期記憶體模型中的缺陷。為了實作JSR133,final和volatile的語義需要重新定義。

完整的語義見:http://www.cs.umd.edu/users/pugh/java/memoryModel,但是正式的語義不是小心翼翼的,它是令人驚訝和清醒的,目的是讓人意識到一些看似簡單的概念(如同步)其實有多複雜。幸運的是,你不需要懂得這些正式語義的細節——JSR133的目的是建立一組正式語義,這些正式語義提供了volatile、synchronzied和final如何工作的直覺架構。

JSR 133的目标包含了:

  • 保留已經存在的安全保證(像類型安全)以及強化其他的安全保證。例如,變量值不能憑空建立:線程觀察到的每個變量的值必須是被其他線程合理的設定的。
  • 正确同步的程式的語義應該盡量簡單和直覺。
  • 應該定義未完成或者未正确同步的程式的語義,主要是為了把潛在的安全危害降到最低。
  • 程式員應該能夠自信的推斷多線程程式如何同記憶體進行互動的。
  • 能夠在現在許多流行的硬體架構中設計正确以及高性能的JVM實作。
  • 應該能提供 安全地初始化的保證。如果一個對象正确的建構了(意思是它的引用沒有在建構的時候逸出,那麼所有能夠看到這個對象的引用的線程,在不進行同步的情況下,也将能看到在構造方法中中設定的final字段的值。
  • 應該盡量不影響現有的代碼。

原文

What is JSR 133 about?

Since 1997, several serious flaws have been discovered in the Java Memory Model as defined in Chapter 17 of the Java Language Specification. These flaws allowed for confusing behaviors (such as final fields being observed to change their value) and undermined the compiler’s ability to perform common optimizations.

The Java Memory Model was an ambitious undertaking; it was the first time that a programming language specification attempted to incorporate a memory model which could provide consistent semantics for concurrency across a variety of architectures. Unfortunately, defining a memory model which is both consistent and intuitive proved far more difficult than expected. JSR 133 defines a new memory model for the Java language which fixes the flaws of the earlier memory model. In order to do this, the semantics of final and volatile needed to change.

The full semantics are available at http://www.cs.umd.edu/users/pugh/java/memoryModel, but the formal semantics are not for the timid. It is surprising, and sobering, to discover how complicated seemingly simple concepts like synchronization really are. Fortunately, you need not understand the details of the formal semantics — the goal of JSR 133 was to create a set of formal semantics that provides an intuitive framework for how volatile, synchronized, and final work.

The goals of JSR 133 include:

  • Preserving existing safety guarantees, like type-safety, and strengthening others. For example, variable values may not be created “out of thin air”: each value for a variable observed by some thread must be a value that can reasonably be placed there by some thread.
  • The semantics of correctly synchronized programs should be as simple and intuitive as possible.
  • The semantics of incompletely or incorrectly synchronized programs should be defined so that potential security hazards are minimized.
  • Programmers should be able to reason confidently about how multithreaded programs interact with memory.
  • It should be possible to design correct, high performance JVM implementations across a wide range of popular hardware architectures.
  • A new guarantee of initialization safety should be provided. If an object is properly constructed (which means that references to it do not escape during construction), then all threads which see a reference to that object will also see the values for its final fields that were set in the constructor, without the need for synchronization.
  • There should be minimal impact on existing code.

原創文章,轉載請注明: 轉載自并發程式設計網 – ifeve.com本文連結位址: Java記憶體模型FAQ(三)JSR133是什麼?

Java記憶體模型FAQ(四)重排序意味着什麼?

原文:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html 第四章

譯者:Alex

在很多情況下,通路一個程式變量(對象執行個體字段,類靜态字段和數組元素)可能會使用不同的順序執行,而不是程式語義所指定的順序執行。編譯器能夠自由的以優化的名義去改變指令順序。在特定的環境下,處理器可能會次序颠倒的執行指令。資料可能在寄存器,處理器緩沖區和主記憶體中以不同的次序移動,而不是按照程式指定的順序。

例如,如果一個線程寫入值到字段a,然後寫入值到字段b,而且b的值不依賴于a的值,那麼,處理器就能夠自由的調整它們的執行順序,而且緩沖區能夠在a之前重新整理b的值到主記憶體。有許多潛在的重排序的來源,例如編譯器,JIT以及緩沖區。

編譯器,運作時和硬體被期望一起協力建立好像是順序執行的語義的假象,這意味着在單線程的程式中,程式應該是不能夠觀察到重排序的影響的。但是,重排序在沒有正确同步了的多線程程式中開始起作用,在這些多線程程式中,一個線程能夠觀察到其他線程的影響,也可能檢測到其他線程将會以一種不同于程式語義所規定的執行順序來通路變量。

大部分情況下,一個線程不會關注其他線程正在做什麼,但是當它需要關注的時候,這時候就需要同步了。

原文

What is meant by reordering?

There are a number of cases in which accesses to program variables (object instance fields, class static fields, and array elements) may appear to execute in a different order than was specified by the program. The compiler is free to take liberties with the ordering of instructions in the name of optimization. Processors may execute instructions out of order under certain circumstances. Data may be moved between registers, processor caches, and main memory in different order than specified by the program.

For example, if a thread writes to field a and then to field b, and the value of b does not depend on the value of a, then the compiler is free to reorder these operations, and the cache is free to flush b to main memory before a. There are a number of potential sources of reordering, such as the compiler, the JIT, and the cache.

The compiler, runtime, and hardware are supposed to conspire to create the illusion of as-if-serial semantics, which means that in a single-threaded program, the program should not be able to observe the effects of reorderings. However, reorderings can come into play in incorrectly synchronized multithreaded programs, where one thread is able to observe the effects of other threads, and may be able to detect that variable accesses become visible to other threads in a different order than executed or specified in the program.

Most of the time, one thread doesn’t care what the other is doing. But when it does, that’s what synchronization is for.

原創文章,轉載請注明: 轉載自并發程式設計網 – ifeve.com本文連結位址: Java記憶體模型FAQ(四)重排序意味着什麼?

Java記憶體模型FAQ(五)舊的記憶體模型有什麼問題?

原文:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html 第五章

譯者:Alex

舊的記憶體模型中有幾個嚴重的問題。這些問題很難了解,是以被廣泛的違背。例如,舊的存儲模型在許多情況下,不允許JVM發生各種重排序行為。舊的記憶體模型中讓人産生困惑的因素造就了JSR-133規範的誕生。

例如,一個被廣泛認可的概念就是,如果使用final字段,那麼就沒有必要在多個線程中使用同步來保證其他線程能夠看到這個字段的值。盡管這是一個合理的假設和明顯的行為,也是我們所期待的結果。實際上,在舊的記憶體模型中,我們想讓程式正确運作起來卻是不行的。在舊的記憶體模型中,final字段并沒有同其他字段進行差別對待——這意味着同步是保證所有線程看到一個在構造方法中初始化的final字段的唯一方法。結果——如果沒有正确同步的話,對一個線程來說,它可能看到一個字段的預設值,然後在稍後的時間裡,又能夠看到構造方法中設定的值。這意味着,一些不可變的對象,例如String,能夠改變它們值——這實在很讓人郁悶。

舊的記憶體模型允許volatile變量的寫操作和非volaitle變量的讀寫操作一起進行重排序,這和大多數的開發人員對于volatile變量的直覺感受是不一緻的,是以會造成迷惑。

最後,我們将看到的是,程式員對于程式沒有被正确同步的情況下将會發生什麼的直覺感受通常是錯誤的。JSR-133的目的之一就是要引起這方面的注意。

原文

What was wrong with the old memory model?

There were several serious problems with the old memory model. It was difficult to understand, and therefore widely violated. For example, the old model did not, in many cases, allow the kinds of reorderings that took place in every JVM. This confusion about the implications of the old model was what compelled the formation of JSR-133.

One widely held belief, for example, was that if final fields were used, then synchronization between threads was unnecessary to guarantee another thread would see the value of the field. While this is a reasonable assumption and a sensible behavior, and indeed how we would want things to work, under the old memory model, it was simply not true. Nothing in the old memory model treated final fields differently from any other field — meaning synchronization was the only way to ensure that all threads see the value of a final field that was written by the constructor. As a result, it was possible for a thread to see the default value of the field, and then at some later time see its constructed value. This means, for example, that immutable objects like String can appear to change their value — a disturbing prospect indeed.

The old memory model allowed for volatile writes to be reordered with nonvolatile reads and writes, which was not consistent with most developers intuitions about volatile and therefore caused confusion.

Finally, as we shall see, programmers’ intuitions about what can occur when their programs are incorrectly synchronized are often mistaken. One of the goals of JSR-133 is to call attention to this fact.

原創文章,轉載請注明: 轉載自并發程式設計網 – ifeve.com本文連結位址: Java記憶體模型FAQ(五)舊的記憶體模型有什麼問題?

Java記憶體模型FAQ(六)沒有正确同步的含義是什麼?

原文:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html 第六章

譯者:Alex

沒有正确同步的代碼對于不同的人來說可能會有不同的了解。在Java記憶體模型這個語義環境下,我們談到“沒有正确同步”,我們的意思是:

  1. 一個線程中有一個對變量的寫操作,
  2. 另外一個線程對同一個變量有讀操作,
  3. 而且寫操作和讀操作沒有通過同步來保證順序。

當這些規則被違反的時候,我們就說在這個變量上有一個“資料競争”(data race)。一個有資料競争的程式就是一個沒有正确同步的程式。

原文

What do you mean by “incorrectly synchronized”?

Incorrectly synchronized code can mean different things to different people. When we talk about incorrectly synchronized code in the context of the Java Memory Model, we mean any code where

  1. there is a write of a variable by one thread,
  2. there is a read of the same variable by another thread and
  3. the write and read are not ordered by synchronization

When these rules are violated, we say we have a data race on that variable. A program with a data race is an incorrectly synchronized program.

原創文章,轉載請注明: 轉載自并發程式設計網 – ifeve.com本文連結位址: Java記憶體模型FAQ(六)沒有正确同步的含義是什麼?