Is ConcurrentSkipListMap.compute() safe for relative updates?
The Javadoc for ConcurrentSkipListMap.compute(K, BiFunction) states:
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). The function is NOT guaranteed to be applied once atomically.
I understand that the function may be invoked multiple times, but what does "once atomically" refer to?
Specifically, is it safe for the function to invoke X = X + 1
without the map value getting incremented multiple times?
java java.util.concurrent concurrentskiplistmap
add a comment |
The Javadoc for ConcurrentSkipListMap.compute(K, BiFunction) states:
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). The function is NOT guaranteed to be applied once atomically.
I understand that the function may be invoked multiple times, but what does "once atomically" refer to?
Specifically, is it safe for the function to invoke X = X + 1
without the map value getting incremented multiple times?
java java.util.concurrent concurrentskiplistmap
1
From the implementation it looks like it would be safe. I think it's just saying that the function could be called more than once.
– shmosel
Nov 15 '18 at 1:02
add a comment |
The Javadoc for ConcurrentSkipListMap.compute(K, BiFunction) states:
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). The function is NOT guaranteed to be applied once atomically.
I understand that the function may be invoked multiple times, but what does "once atomically" refer to?
Specifically, is it safe for the function to invoke X = X + 1
without the map value getting incremented multiple times?
java java.util.concurrent concurrentskiplistmap
The Javadoc for ConcurrentSkipListMap.compute(K, BiFunction) states:
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). The function is NOT guaranteed to be applied once atomically.
I understand that the function may be invoked multiple times, but what does "once atomically" refer to?
Specifically, is it safe for the function to invoke X = X + 1
without the map value getting incremented multiple times?
java java.util.concurrent concurrentskiplistmap
java java.util.concurrent concurrentskiplistmap
edited Nov 15 '18 at 0:52
Gili
asked Nov 15 '18 at 0:51
GiliGili
41.5k62276524
41.5k62276524
1
From the implementation it looks like it would be safe. I think it's just saying that the function could be called more than once.
– shmosel
Nov 15 '18 at 1:02
add a comment |
1
From the implementation it looks like it would be safe. I think it's just saying that the function could be called more than once.
– shmosel
Nov 15 '18 at 1:02
1
1
From the implementation it looks like it would be safe. I think it's just saying that the function could be called more than once.
– shmosel
Nov 15 '18 at 1:02
From the implementation it looks like it would be safe. I think it's just saying that the function could be called more than once.
– shmosel
Nov 15 '18 at 1:02
add a comment |
1 Answer
1
active
oldest
votes
It is saying that:
- the function could be called more than once, and
- those calls could overlap in time; i.e. if multiple threads are calling
compute
simultaneously.
In other words, do not expect atomic behavior in the way that the function reference is called by compute
.
Specifically, is it safe for the function to invoke X = X + 1 without the map value getting incremented multiple times?
It depends on what mean by "invoke X = X + 1". (You didn't include a clear example ....)
If the
x = x + 1
means that you are just trying to increment the map's value, then:
One call to
compute
will only result in one "incrementation", because of the definition in thecompute
inConcurrentMap
.But when you return from
compute
the value could have been incremented more than once, because another thread was doing the same thing simultaneously.
If the
x = x + 1
refers to a side-effect of the method reference, then all bets are off:
- It may have happened multiple times.
- If your method reference is not properly synchronized, etcetera, there could be all sorts of nasty effects. The spec implies that the
compute
call is not going to synchronize externally or call the method reference in a mutex or anything like that. Normal concurrency / memory rules apply ...
Why would they overlap in time?
– shmosel
Nov 15 '18 at 1:17
Because multiple threads could be callingcompute
. For the same key.
– Stephen C
Nov 15 '18 at 1:18
Seems like a weird use of "atomically" though. By that definition,AtomicInteger.getAndUpdate()
is not atomic either.
– shmosel
Nov 15 '18 at 1:23
@shmosel - It is not a definition. It is an anti-definition. It is a statement that is intended to dispel misconceptions / false assumptions. But yes you are correct. They don't strictly need to say "atomic". And they could have said "not guaranteed to be called once atomically" about the call(s) to the function ingetAndUpdate
. Instead, they simply say that the function may be called more than once ... which is probably sufficient.
– Stephen C
Nov 15 '18 at 1:32
1
Hmmm ... sort of. "The overall effects are atomic" is conditional on a sensible implementation of theBiFunction
. That matters because (as you point out) if the CAS fails you need to all the function again ... and again ... until it succeeds. BTW, that behavior is part of the spec, not just an implementation detail; see the superclass javadocs
– Stephen C
Nov 15 '18 at 7:05
|
show 8 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310936%2fis-concurrentskiplistmap-compute-safe-for-relative-updates%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It is saying that:
- the function could be called more than once, and
- those calls could overlap in time; i.e. if multiple threads are calling
compute
simultaneously.
In other words, do not expect atomic behavior in the way that the function reference is called by compute
.
Specifically, is it safe for the function to invoke X = X + 1 without the map value getting incremented multiple times?
It depends on what mean by "invoke X = X + 1". (You didn't include a clear example ....)
If the
x = x + 1
means that you are just trying to increment the map's value, then:
One call to
compute
will only result in one "incrementation", because of the definition in thecompute
inConcurrentMap
.But when you return from
compute
the value could have been incremented more than once, because another thread was doing the same thing simultaneously.
If the
x = x + 1
refers to a side-effect of the method reference, then all bets are off:
- It may have happened multiple times.
- If your method reference is not properly synchronized, etcetera, there could be all sorts of nasty effects. The spec implies that the
compute
call is not going to synchronize externally or call the method reference in a mutex or anything like that. Normal concurrency / memory rules apply ...
Why would they overlap in time?
– shmosel
Nov 15 '18 at 1:17
Because multiple threads could be callingcompute
. For the same key.
– Stephen C
Nov 15 '18 at 1:18
Seems like a weird use of "atomically" though. By that definition,AtomicInteger.getAndUpdate()
is not atomic either.
– shmosel
Nov 15 '18 at 1:23
@shmosel - It is not a definition. It is an anti-definition. It is a statement that is intended to dispel misconceptions / false assumptions. But yes you are correct. They don't strictly need to say "atomic". And they could have said "not guaranteed to be called once atomically" about the call(s) to the function ingetAndUpdate
. Instead, they simply say that the function may be called more than once ... which is probably sufficient.
– Stephen C
Nov 15 '18 at 1:32
1
Hmmm ... sort of. "The overall effects are atomic" is conditional on a sensible implementation of theBiFunction
. That matters because (as you point out) if the CAS fails you need to all the function again ... and again ... until it succeeds. BTW, that behavior is part of the spec, not just an implementation detail; see the superclass javadocs
– Stephen C
Nov 15 '18 at 7:05
|
show 8 more comments
It is saying that:
- the function could be called more than once, and
- those calls could overlap in time; i.e. if multiple threads are calling
compute
simultaneously.
In other words, do not expect atomic behavior in the way that the function reference is called by compute
.
Specifically, is it safe for the function to invoke X = X + 1 without the map value getting incremented multiple times?
It depends on what mean by "invoke X = X + 1". (You didn't include a clear example ....)
If the
x = x + 1
means that you are just trying to increment the map's value, then:
One call to
compute
will only result in one "incrementation", because of the definition in thecompute
inConcurrentMap
.But when you return from
compute
the value could have been incremented more than once, because another thread was doing the same thing simultaneously.
If the
x = x + 1
refers to a side-effect of the method reference, then all bets are off:
- It may have happened multiple times.
- If your method reference is not properly synchronized, etcetera, there could be all sorts of nasty effects. The spec implies that the
compute
call is not going to synchronize externally or call the method reference in a mutex or anything like that. Normal concurrency / memory rules apply ...
Why would they overlap in time?
– shmosel
Nov 15 '18 at 1:17
Because multiple threads could be callingcompute
. For the same key.
– Stephen C
Nov 15 '18 at 1:18
Seems like a weird use of "atomically" though. By that definition,AtomicInteger.getAndUpdate()
is not atomic either.
– shmosel
Nov 15 '18 at 1:23
@shmosel - It is not a definition. It is an anti-definition. It is a statement that is intended to dispel misconceptions / false assumptions. But yes you are correct. They don't strictly need to say "atomic". And they could have said "not guaranteed to be called once atomically" about the call(s) to the function ingetAndUpdate
. Instead, they simply say that the function may be called more than once ... which is probably sufficient.
– Stephen C
Nov 15 '18 at 1:32
1
Hmmm ... sort of. "The overall effects are atomic" is conditional on a sensible implementation of theBiFunction
. That matters because (as you point out) if the CAS fails you need to all the function again ... and again ... until it succeeds. BTW, that behavior is part of the spec, not just an implementation detail; see the superclass javadocs
– Stephen C
Nov 15 '18 at 7:05
|
show 8 more comments
It is saying that:
- the function could be called more than once, and
- those calls could overlap in time; i.e. if multiple threads are calling
compute
simultaneously.
In other words, do not expect atomic behavior in the way that the function reference is called by compute
.
Specifically, is it safe for the function to invoke X = X + 1 without the map value getting incremented multiple times?
It depends on what mean by "invoke X = X + 1". (You didn't include a clear example ....)
If the
x = x + 1
means that you are just trying to increment the map's value, then:
One call to
compute
will only result in one "incrementation", because of the definition in thecompute
inConcurrentMap
.But when you return from
compute
the value could have been incremented more than once, because another thread was doing the same thing simultaneously.
If the
x = x + 1
refers to a side-effect of the method reference, then all bets are off:
- It may have happened multiple times.
- If your method reference is not properly synchronized, etcetera, there could be all sorts of nasty effects. The spec implies that the
compute
call is not going to synchronize externally or call the method reference in a mutex or anything like that. Normal concurrency / memory rules apply ...
It is saying that:
- the function could be called more than once, and
- those calls could overlap in time; i.e. if multiple threads are calling
compute
simultaneously.
In other words, do not expect atomic behavior in the way that the function reference is called by compute
.
Specifically, is it safe for the function to invoke X = X + 1 without the map value getting incremented multiple times?
It depends on what mean by "invoke X = X + 1". (You didn't include a clear example ....)
If the
x = x + 1
means that you are just trying to increment the map's value, then:
One call to
compute
will only result in one "incrementation", because of the definition in thecompute
inConcurrentMap
.But when you return from
compute
the value could have been incremented more than once, because another thread was doing the same thing simultaneously.
If the
x = x + 1
refers to a side-effect of the method reference, then all bets are off:
- It may have happened multiple times.
- If your method reference is not properly synchronized, etcetera, there could be all sorts of nasty effects. The spec implies that the
compute
call is not going to synchronize externally or call the method reference in a mutex or anything like that. Normal concurrency / memory rules apply ...
edited Nov 15 '18 at 4:16
answered Nov 15 '18 at 1:16
Stephen CStephen C
521k70578937
521k70578937
Why would they overlap in time?
– shmosel
Nov 15 '18 at 1:17
Because multiple threads could be callingcompute
. For the same key.
– Stephen C
Nov 15 '18 at 1:18
Seems like a weird use of "atomically" though. By that definition,AtomicInteger.getAndUpdate()
is not atomic either.
– shmosel
Nov 15 '18 at 1:23
@shmosel - It is not a definition. It is an anti-definition. It is a statement that is intended to dispel misconceptions / false assumptions. But yes you are correct. They don't strictly need to say "atomic". And they could have said "not guaranteed to be called once atomically" about the call(s) to the function ingetAndUpdate
. Instead, they simply say that the function may be called more than once ... which is probably sufficient.
– Stephen C
Nov 15 '18 at 1:32
1
Hmmm ... sort of. "The overall effects are atomic" is conditional on a sensible implementation of theBiFunction
. That matters because (as you point out) if the CAS fails you need to all the function again ... and again ... until it succeeds. BTW, that behavior is part of the spec, not just an implementation detail; see the superclass javadocs
– Stephen C
Nov 15 '18 at 7:05
|
show 8 more comments
Why would they overlap in time?
– shmosel
Nov 15 '18 at 1:17
Because multiple threads could be callingcompute
. For the same key.
– Stephen C
Nov 15 '18 at 1:18
Seems like a weird use of "atomically" though. By that definition,AtomicInteger.getAndUpdate()
is not atomic either.
– shmosel
Nov 15 '18 at 1:23
@shmosel - It is not a definition. It is an anti-definition. It is a statement that is intended to dispel misconceptions / false assumptions. But yes you are correct. They don't strictly need to say "atomic". And they could have said "not guaranteed to be called once atomically" about the call(s) to the function ingetAndUpdate
. Instead, they simply say that the function may be called more than once ... which is probably sufficient.
– Stephen C
Nov 15 '18 at 1:32
1
Hmmm ... sort of. "The overall effects are atomic" is conditional on a sensible implementation of theBiFunction
. That matters because (as you point out) if the CAS fails you need to all the function again ... and again ... until it succeeds. BTW, that behavior is part of the spec, not just an implementation detail; see the superclass javadocs
– Stephen C
Nov 15 '18 at 7:05
Why would they overlap in time?
– shmosel
Nov 15 '18 at 1:17
Why would they overlap in time?
– shmosel
Nov 15 '18 at 1:17
Because multiple threads could be calling
compute
. For the same key.– Stephen C
Nov 15 '18 at 1:18
Because multiple threads could be calling
compute
. For the same key.– Stephen C
Nov 15 '18 at 1:18
Seems like a weird use of "atomically" though. By that definition,
AtomicInteger.getAndUpdate()
is not atomic either.– shmosel
Nov 15 '18 at 1:23
Seems like a weird use of "atomically" though. By that definition,
AtomicInteger.getAndUpdate()
is not atomic either.– shmosel
Nov 15 '18 at 1:23
@shmosel - It is not a definition. It is an anti-definition. It is a statement that is intended to dispel misconceptions / false assumptions. But yes you are correct. They don't strictly need to say "atomic". And they could have said "not guaranteed to be called once atomically" about the call(s) to the function in
getAndUpdate
. Instead, they simply say that the function may be called more than once ... which is probably sufficient.– Stephen C
Nov 15 '18 at 1:32
@shmosel - It is not a definition. It is an anti-definition. It is a statement that is intended to dispel misconceptions / false assumptions. But yes you are correct. They don't strictly need to say "atomic". And they could have said "not guaranteed to be called once atomically" about the call(s) to the function in
getAndUpdate
. Instead, they simply say that the function may be called more than once ... which is probably sufficient.– Stephen C
Nov 15 '18 at 1:32
1
1
Hmmm ... sort of. "The overall effects are atomic" is conditional on a sensible implementation of the
BiFunction
. That matters because (as you point out) if the CAS fails you need to all the function again ... and again ... until it succeeds. BTW, that behavior is part of the spec, not just an implementation detail; see the superclass javadocs– Stephen C
Nov 15 '18 at 7:05
Hmmm ... sort of. "The overall effects are atomic" is conditional on a sensible implementation of the
BiFunction
. That matters because (as you point out) if the CAS fails you need to all the function again ... and again ... until it succeeds. BTW, that behavior is part of the spec, not just an implementation detail; see the superclass javadocs– Stephen C
Nov 15 '18 at 7:05
|
show 8 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310936%2fis-concurrentskiplistmap-compute-safe-for-relative-updates%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
From the implementation it looks like it would be safe. I think it's just saying that the function could be called more than once.
– shmosel
Nov 15 '18 at 1:02