atomicLong within java streams

nimo23 :

I cannot decrement a common Long-value within a stream (outer declared value used within streams must be final), so I must use AtomicLong within java streams:

var users = Stream<User> getUsers();
var dec = new AtomicLong(10);
long dec = 10;

// users is a 
users.forEach(u->{

// does not work within streams, so I have to use AtomicLong
dec--;

// this works
dec.decrementAndGet();


// which one should I use, if I only want to get the raw value?
long actualValue = dec.getPlain();
long actualValue = dec.get(); // the same as dec.getOpaque();

});

I cannot see any differences between dec.getPlain() and dec.get(). I dont understand the

with memory semantics of reading

described in the API. Where lies the differences in those methods?

Which should I use if I only have one thread which reads the actualValue.

Donat :

The difference is the method for fetching the result from memory. I. e. if it is read as if declared as volatile or as a normal variable. volatile is for variables which are being accessed concurrently by more than one thread. When normal varaibles are being changed by one thread, the other threads may never see the change because each thread may hold the variable in its own cache. volatile variables must always be read and written from common memory (not cache). This makes access slower but reliable when used concurrently.

When you do not use the value concurrently, the method getPlain() is sufficient and it should be faster. But using AtomicLong for side effects with a stream is kind of a misuse because when programming in a functional way, you should not depend on side effects.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=164473&siteId=1