Is ConcurrentSkipListMap.compute() safe for relative updates?












1















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?










share|improve this question




















  • 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















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?










share|improve this question




















  • 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








1








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 0:52







Gili

















asked Nov 15 '18 at 0:51









GiliGili

41.3k62276522




41.3k62276522








  • 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





    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












1 Answer
1






active

oldest

votes


















2














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 the compute in ConcurrentMap.


    • 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 ...








share|improve this answer


























  • 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













  • 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






  • 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













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
});


}
});














draft saved

draft discarded


















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









2














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 the compute in ConcurrentMap.


    • 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 ...








share|improve this answer


























  • 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













  • 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






  • 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


















2














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 the compute in ConcurrentMap.


    • 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 ...








share|improve this answer


























  • 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













  • 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






  • 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
















2












2








2







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 the compute in ConcurrentMap.


    • 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 ...








share|improve this answer















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 the compute in ConcurrentMap.


    • 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 ...









share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 '18 at 4:16

























answered Nov 15 '18 at 1:16









Stephen CStephen C

520k70577937




520k70577937













  • 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













  • 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






  • 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





















  • 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













  • 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






  • 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



















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






















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python