Concurrent access to Java HashMap object












1















I'm building a Java REST application where I'm using a HashMap to store some data.



As it has a server, it can handle multiple requests simultaneously that access the HashMap. All requests made check if the Map has a predefined value (that value depends on the request body) and if not, add that value to the Map and return it. In case the Map has that value already, it simply returns the value on the Map.



What should I take into consideration in order to have a working and reliable system? I will have many reads on the Map and some writes (mainly when the application starts as the Map will be empty).



tl;dr




  • Java Server which will handle multiple and simultaneous requests.

  • Every request will make at least a Map.containsKey(someKey) and eventually a Map.get(someKey)

  • Some requests will make a Map.put(someKey, someValue)


Shall I use some kind of concurrent data structure?



For the sake of argument, I know that using an in-memory solution is not reliable. This is not intended for production use, it is merely academical.










share|improve this question




















  • 2





    "What should I take into consideration in order to have a working and reliable system" from a reliability perspective, any kind of in-memory storage is a poor choice.

    – Andy Turner
    Jan 20 at 9:40











  • docs.oracle.com/javase/8/docs/api/java/util/concurrent/… But the map may change from the point it reads "containsKey", to the point where a "get" is made. In that case locking may be the solution, but that will impact performance.

    – Jeppe
    Jan 20 at 9:44






  • 2





    I think you need to specify your requirements in detail. If you simply require a thread-safe solution (race-conditions/thread visibility), then ConcurrentHashMap should work. But if it is important that the first request is also the final value throughout the lifetime of the map, then it might not be enough (if values differ), as two threads can end up getting false from containsKey, and then both call put. In that case you need containsKey and put to be an atomic operation.

    – Jeppe
    Jan 20 at 10:10








  • 2





    @Jeppe: That atomic operation is provided by ConcurrentMap#computeIfAbsent

    – Thilo
    Jan 20 at 11:14






  • 1





    @Thilo wouldn't ConcurrentMap#putIfAbsent be a better option then? That way I wouldn't need to write the code to insert in the map as the method itself would do it

    – LuisF
    Jan 20 at 12:10
















1















I'm building a Java REST application where I'm using a HashMap to store some data.



As it has a server, it can handle multiple requests simultaneously that access the HashMap. All requests made check if the Map has a predefined value (that value depends on the request body) and if not, add that value to the Map and return it. In case the Map has that value already, it simply returns the value on the Map.



What should I take into consideration in order to have a working and reliable system? I will have many reads on the Map and some writes (mainly when the application starts as the Map will be empty).



tl;dr




  • Java Server which will handle multiple and simultaneous requests.

  • Every request will make at least a Map.containsKey(someKey) and eventually a Map.get(someKey)

  • Some requests will make a Map.put(someKey, someValue)


Shall I use some kind of concurrent data structure?



For the sake of argument, I know that using an in-memory solution is not reliable. This is not intended for production use, it is merely academical.










share|improve this question




















  • 2





    "What should I take into consideration in order to have a working and reliable system" from a reliability perspective, any kind of in-memory storage is a poor choice.

    – Andy Turner
    Jan 20 at 9:40











  • docs.oracle.com/javase/8/docs/api/java/util/concurrent/… But the map may change from the point it reads "containsKey", to the point where a "get" is made. In that case locking may be the solution, but that will impact performance.

    – Jeppe
    Jan 20 at 9:44






  • 2





    I think you need to specify your requirements in detail. If you simply require a thread-safe solution (race-conditions/thread visibility), then ConcurrentHashMap should work. But if it is important that the first request is also the final value throughout the lifetime of the map, then it might not be enough (if values differ), as two threads can end up getting false from containsKey, and then both call put. In that case you need containsKey and put to be an atomic operation.

    – Jeppe
    Jan 20 at 10:10








  • 2





    @Jeppe: That atomic operation is provided by ConcurrentMap#computeIfAbsent

    – Thilo
    Jan 20 at 11:14






  • 1





    @Thilo wouldn't ConcurrentMap#putIfAbsent be a better option then? That way I wouldn't need to write the code to insert in the map as the method itself would do it

    – LuisF
    Jan 20 at 12:10














1












1








1








I'm building a Java REST application where I'm using a HashMap to store some data.



As it has a server, it can handle multiple requests simultaneously that access the HashMap. All requests made check if the Map has a predefined value (that value depends on the request body) and if not, add that value to the Map and return it. In case the Map has that value already, it simply returns the value on the Map.



What should I take into consideration in order to have a working and reliable system? I will have many reads on the Map and some writes (mainly when the application starts as the Map will be empty).



tl;dr




  • Java Server which will handle multiple and simultaneous requests.

  • Every request will make at least a Map.containsKey(someKey) and eventually a Map.get(someKey)

  • Some requests will make a Map.put(someKey, someValue)


Shall I use some kind of concurrent data structure?



For the sake of argument, I know that using an in-memory solution is not reliable. This is not intended for production use, it is merely academical.










share|improve this question
















I'm building a Java REST application where I'm using a HashMap to store some data.



As it has a server, it can handle multiple requests simultaneously that access the HashMap. All requests made check if the Map has a predefined value (that value depends on the request body) and if not, add that value to the Map and return it. In case the Map has that value already, it simply returns the value on the Map.



What should I take into consideration in order to have a working and reliable system? I will have many reads on the Map and some writes (mainly when the application starts as the Map will be empty).



tl;dr




  • Java Server which will handle multiple and simultaneous requests.

  • Every request will make at least a Map.containsKey(someKey) and eventually a Map.get(someKey)

  • Some requests will make a Map.put(someKey, someValue)


Shall I use some kind of concurrent data structure?



For the sake of argument, I know that using an in-memory solution is not reliable. This is not intended for production use, it is merely academical.







java dictionary concurrency concurrenthashmap






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 20 at 9:54







LuisF

















asked Jan 20 at 9:37









LuisFLuisF

17612




17612








  • 2





    "What should I take into consideration in order to have a working and reliable system" from a reliability perspective, any kind of in-memory storage is a poor choice.

    – Andy Turner
    Jan 20 at 9:40











  • docs.oracle.com/javase/8/docs/api/java/util/concurrent/… But the map may change from the point it reads "containsKey", to the point where a "get" is made. In that case locking may be the solution, but that will impact performance.

    – Jeppe
    Jan 20 at 9:44






  • 2





    I think you need to specify your requirements in detail. If you simply require a thread-safe solution (race-conditions/thread visibility), then ConcurrentHashMap should work. But if it is important that the first request is also the final value throughout the lifetime of the map, then it might not be enough (if values differ), as two threads can end up getting false from containsKey, and then both call put. In that case you need containsKey and put to be an atomic operation.

    – Jeppe
    Jan 20 at 10:10








  • 2





    @Jeppe: That atomic operation is provided by ConcurrentMap#computeIfAbsent

    – Thilo
    Jan 20 at 11:14






  • 1





    @Thilo wouldn't ConcurrentMap#putIfAbsent be a better option then? That way I wouldn't need to write the code to insert in the map as the method itself would do it

    – LuisF
    Jan 20 at 12:10














  • 2





    "What should I take into consideration in order to have a working and reliable system" from a reliability perspective, any kind of in-memory storage is a poor choice.

    – Andy Turner
    Jan 20 at 9:40











  • docs.oracle.com/javase/8/docs/api/java/util/concurrent/… But the map may change from the point it reads "containsKey", to the point where a "get" is made. In that case locking may be the solution, but that will impact performance.

    – Jeppe
    Jan 20 at 9:44






  • 2





    I think you need to specify your requirements in detail. If you simply require a thread-safe solution (race-conditions/thread visibility), then ConcurrentHashMap should work. But if it is important that the first request is also the final value throughout the lifetime of the map, then it might not be enough (if values differ), as two threads can end up getting false from containsKey, and then both call put. In that case you need containsKey and put to be an atomic operation.

    – Jeppe
    Jan 20 at 10:10








  • 2





    @Jeppe: That atomic operation is provided by ConcurrentMap#computeIfAbsent

    – Thilo
    Jan 20 at 11:14






  • 1





    @Thilo wouldn't ConcurrentMap#putIfAbsent be a better option then? That way I wouldn't need to write the code to insert in the map as the method itself would do it

    – LuisF
    Jan 20 at 12:10








2




2





"What should I take into consideration in order to have a working and reliable system" from a reliability perspective, any kind of in-memory storage is a poor choice.

– Andy Turner
Jan 20 at 9:40





"What should I take into consideration in order to have a working and reliable system" from a reliability perspective, any kind of in-memory storage is a poor choice.

– Andy Turner
Jan 20 at 9:40













docs.oracle.com/javase/8/docs/api/java/util/concurrent/… But the map may change from the point it reads "containsKey", to the point where a "get" is made. In that case locking may be the solution, but that will impact performance.

– Jeppe
Jan 20 at 9:44





docs.oracle.com/javase/8/docs/api/java/util/concurrent/… But the map may change from the point it reads "containsKey", to the point where a "get" is made. In that case locking may be the solution, but that will impact performance.

– Jeppe
Jan 20 at 9:44




2




2





I think you need to specify your requirements in detail. If you simply require a thread-safe solution (race-conditions/thread visibility), then ConcurrentHashMap should work. But if it is important that the first request is also the final value throughout the lifetime of the map, then it might not be enough (if values differ), as two threads can end up getting false from containsKey, and then both call put. In that case you need containsKey and put to be an atomic operation.

– Jeppe
Jan 20 at 10:10







I think you need to specify your requirements in detail. If you simply require a thread-safe solution (race-conditions/thread visibility), then ConcurrentHashMap should work. But if it is important that the first request is also the final value throughout the lifetime of the map, then it might not be enough (if values differ), as two threads can end up getting false from containsKey, and then both call put. In that case you need containsKey and put to be an atomic operation.

– Jeppe
Jan 20 at 10:10






2




2





@Jeppe: That atomic operation is provided by ConcurrentMap#computeIfAbsent

– Thilo
Jan 20 at 11:14





@Jeppe: That atomic operation is provided by ConcurrentMap#computeIfAbsent

– Thilo
Jan 20 at 11:14




1




1





@Thilo wouldn't ConcurrentMap#putIfAbsent be a better option then? That way I wouldn't need to write the code to insert in the map as the method itself would do it

– LuisF
Jan 20 at 12:10





@Thilo wouldn't ConcurrentMap#putIfAbsent be a better option then? That way I wouldn't need to write the code to insert in the map as the method itself would do it

– LuisF
Jan 20 at 12:10












1 Answer
1






active

oldest

votes


















0














If you want to keep it in memory, you need to use a ConcurrentHashMap.



But what happens if you restart the application and lose the memory data?






share|improve this answer
























  • it is an kind of an academical exercise, I know that the best approach would be to persist it in a DB for example

    – LuisF
    Jan 20 at 9:49











  • Understood. Than use the ConcurrentHashMap.

    – Cristi
    Jan 23 at 11:39











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%2f54275168%2fconcurrent-access-to-java-hashmap-object%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









0














If you want to keep it in memory, you need to use a ConcurrentHashMap.



But what happens if you restart the application and lose the memory data?






share|improve this answer
























  • it is an kind of an academical exercise, I know that the best approach would be to persist it in a DB for example

    – LuisF
    Jan 20 at 9:49











  • Understood. Than use the ConcurrentHashMap.

    – Cristi
    Jan 23 at 11:39
















0














If you want to keep it in memory, you need to use a ConcurrentHashMap.



But what happens if you restart the application and lose the memory data?






share|improve this answer
























  • it is an kind of an academical exercise, I know that the best approach would be to persist it in a DB for example

    – LuisF
    Jan 20 at 9:49











  • Understood. Than use the ConcurrentHashMap.

    – Cristi
    Jan 23 at 11:39














0












0








0







If you want to keep it in memory, you need to use a ConcurrentHashMap.



But what happens if you restart the application and lose the memory data?






share|improve this answer













If you want to keep it in memory, you need to use a ConcurrentHashMap.



But what happens if you restart the application and lose the memory data?







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 20 at 9:44









CristiCristi

508




508













  • it is an kind of an academical exercise, I know that the best approach would be to persist it in a DB for example

    – LuisF
    Jan 20 at 9:49











  • Understood. Than use the ConcurrentHashMap.

    – Cristi
    Jan 23 at 11:39



















  • it is an kind of an academical exercise, I know that the best approach would be to persist it in a DB for example

    – LuisF
    Jan 20 at 9:49











  • Understood. Than use the ConcurrentHashMap.

    – Cristi
    Jan 23 at 11:39

















it is an kind of an academical exercise, I know that the best approach would be to persist it in a DB for example

– LuisF
Jan 20 at 9:49





it is an kind of an academical exercise, I know that the best approach would be to persist it in a DB for example

– LuisF
Jan 20 at 9:49













Understood. Than use the ConcurrentHashMap.

– Cristi
Jan 23 at 11:39





Understood. Than use the ConcurrentHashMap.

– Cristi
Jan 23 at 11:39




















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%2f54275168%2fconcurrent-access-to-java-hashmap-object%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

Callistus III

Plistias Cous

Index Sanctorum