Non-interference exact meaning in Java 8 threads

Is the requirement of non-interference required to use streams of non-competitive sources of the data structure that we cannot change the state of the data structure element during the execution of the stream pipeline (in addition to this, we can’t "change the original data structure)? (Question 1)

The non-interference section in the description of the stream package states: "For most data sources, interference prevention means that the data source will not be altered at all during the execution of the stream pipeline."

Does this passage not mention the state change of elements?

For example, assuming “shapes” are not a thread-safe collection (such as an ArrayList ), is the code below a hindrance? (Question 2)

 shapes.stream() .filter(s -> s.getColor() == BLUE) .forEach(s -> s.setColor(RED)); 

This example is taken from a reliable source (at least), so it should be correct. But what if I changed stream() to parallelStream() , would it still be safe and correct? (Question 3)

On the other hand, the “Development of Lambdas” by Naftalin Moris, another reliable source, makes it clear that a change in the state (value) of elements in a pipeline operation is indeed an obstacle. From the section on non-intervention (3.2.3):

"But the rules for threads forbid any modification of the sources of a stream, including, for example, changing the value of an element - for any stream, and not just operations with the pipeline."

If what is said in the book is correct, does this mean that we cannot use the stream API to change the state of elements (using forEach ) and should do it using a regular iterator (or for each, or Iterable.forEach )? (Question 4)

+6
source share
2 answers

There is a higher class of functions called "side effect functions". The JavaDoc statement is correct and complete: here, intervention means changing a mutable source. Another case is expressions with a state expression: expressions that depend on the state of the application or change this state. You can read the Parallelism tutorial on the Oracle website.

In general, you can change the elements of the stream yourself, and it should not be called "interference". Beware though if you have the same mutable object that is generated several times by the stream source (for example, using Collections.nCopies(10, new MyMutableObject()).parallelStream() . Although it guarantees the same a stream item is not processed simultaneously by several threads, if your thread generates the same item twice, you can probably have a race condition when modifying in forEach , for example.

Thus, although state expressions sometimes smell and should be used with care and avoided if there is an alternative to statelessness, they are probably good if they do not interfere with the source of the stream. If a stateless expression is required (for example, in the Stream.map method), it is specifically mentioned in the API docs. The forEach documentation only requires non-interference.

So, back to your questions:

Question 1: no, we can change the state of an element, and this is not called a hindrance (although it is called statefullness)

Question 2: there is no interference if you do not repeat the objects in the stream source)

Question 3: you can use parallelStream() safely there

Question 4: no, you can use the Stream API in this case.

+6
source

Changing the state of an object stored in a data structure is different from reassigning a data structure element.

When another writes "change the value of an element", they seem to mean that they are assigning a new object to the index of an existing List .

From link :

It is best to avoid any side effects in the methods that lambdas passes to threads. While some side effects, such as debug statements that print values, are usually safe, accessing the mutable state from these lambdas can lead to data gons or unexpected behavior, since lambdas can execute from many threads simultaneously and cannot see elements in their natural meeting order. Non-interference includes not only not disturbing the source, but not disturbing other lambdas; this kind of interference can occur when one lambda changes a volatile state and the other lambda reads it.

As long as the requirement of non-interference is met, we can perform concurrent operations safely and with predictable results even in non-stream sources such as ArrayList.

This applies to parallelism and is no different from any other parallel programming. A change in state can cause visibility problems among threads.

+1
source

All Articles