Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding intra-thread semantics

Could you explain in simple words what "the program satisfies intra-thread semantic" means? Is it possible to provide simple examples of programs which satisfy and which don't satisfy such semantics?

like image 819
St.Antario Avatar asked Dec 12 '22 03:12

St.Antario


2 Answers

The notion of intra-thread semantics is discussed in the JLS section 17.4, which covers the Java Memory Model. The JMM is a set of requirements and constraints on the execution of Java programs by JVMs. Here's the relevant section of text from 17.4:

The memory model determines what values can be read at every point in the program. The actions of each thread in isolation must behave as governed by the semantics of that thread, with the exception that the values seen by each read are determined by the memory model. When we refer to this, we say that the program obeys intra-thread semantics. Intra-thread semantics are the semantics for single-threaded programs, and allow the complete prediction of the behavior of a thread based on the values seen by read actions within the thread. To determine if the actions of thread t in an execution are legal, we simply evaluate the implementation of thread t as it would be performed in a single-threaded context, as defined in the rest of this specification.

This means that, as far as a single thread is concerned, the values visible in objects' fields are either the fields' initial values (zero, false, or null) or are values that this thread has previously written.

This is so obvious as to be elementary; why bother stating it?

Consider a single-threaded Java program with a few int fields:

field1 = 1;                // 1
field2 = 2;                // 2
field3 = field1 + field2;  // 3

then clearly the value of field3 must be 3. This is because the values visible in field1 and field2 at line 3 must reflect the earlier values written at lines 1 and 2. It would be incorrect if the initial value of zero for field1 or field2 were used in the computation at line 3, since the assignment of those fields occurs earlier in the program than the computation.

What is less obvious are the constraints that are not present. For example, there is no constraint here over the ordering of the writes of field1 and field2. The JVM could execute line 2 before line 1 and the result of the program would be the same. Or, it could delay the writes to field1 and field2 and keep these values in registers, and do register-based addition at line 3. The actual writes of all the fields could be delayed until much later. Or they could even be omitted entirely if the values are subsequently overwritten by this thread. Again, the outcome of the program would be the same.

And that's the point: JVMs are free to rearrange the execution of a program (mainly so that it can run faster), but only as long it doesn't change the results of that program if it were run single-threaded. These constraints are referred to as intra-thread semantics. Any rearrangements that don't violate intra-thread semantics are permitted.

(Note that the paragraph quoted above talks about a "program that obeys intra-thread semantics" but what it really means is the execution of the program obeys intra-thread semantics. Text in later sections, such as 17.4.7, is more precise, referring to whether an execution of a program obeys intra-thread consistency or whether a set of actions performed is in accord with intra-thread semantics.)

like image 156
Stuart Marks Avatar answered Dec 21 '22 01:12

Stuart Marks


Let's break this down: https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4

1 The memory model determines what values can be read at every point in the program. 2 The actions of each thread in isolation must behave as governed by the semantics of that thread, 3 with the exception that the values seen by each read are determined by the memory model. 4 When we refer to this, we say that the program obeys intra-thread semantics. Intra-thread semantics are the semantics for single-threaded programs, and allow the complete prediction of the behavior of a thread based on the values seen by read actions within the thread

1. The memory model determines what values can be read at every point in the program

It means the JMM have rules for visibility and ordering that dictates the values for reads - rules that haven't been defined yet but makes the reader aware that they exist (they explain in 3 and 4 how it relates to intra-thread semantics)

2. The actions of each thread in isolation must behave as governed by the semantics of that thread

It does not define what is "isolation" in this context, nor what is "semantics of that thread" but they probably meant Actions that do not fall under inter-thread actions, so all actions done by a thread that don't influence other threads will be read line by line (semantics of thread). Their "definition" for intra-thread actions (sort of, they only give an example) is:

"This specification is only concerned with inter-thread actions. We do not need to concern ourselves with intra-thread actions (e.g., adding two local variables and storing the result in a third local variable)" - ie any action that won't effect any shared memory.

3. with the exception that the values seen by each read are determined by the memory model.

It means that the JMM apply its rules even when a thread executes code that have no influence on any other thread (2) - it dictates the values of these reads.

4. When we refer to this, we say that the program obeys intra-thread semantics. Intra-thread semantics are the semantics for single-threaded programs, and allow the complete prediction of the behavior of a thread based on the values seen by read actions within the thread

To sum it up, they are saying - If you have a thread that perform an action in isolation, meaning manipulates (read or write) data not in any shared memory. the value of reads in that code would still be *decided by the JMM and all of it (complete) would be known to that same thread - This is what it means to obey intra-thread semantics


They almost implicitly describe here Sequential Consistency (SC) without actually saying it, the only missing part is inter-thread actions - This is described to be used later on in Program Order (*decided by the JMM) which needed all the definitions here to define when is SC used.

Program orders is the rule they kept mentioning without naming before, it says that if you look at all (total) the actions (intra and inter) in a thread and consider them as intra-thread semantic then they are all considered Sequential Consistent.


  • You can understand what is SC by reading Stuart Marks answer

  • As a side note I just have to say the phrasing in JLS for JMM is horrendous, they could not have made it more confusing if they tried to.

like image 36
Dopefish Avatar answered Dec 21 '22 01:12

Dopefish