Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8404737
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T22:40:34+00:00 2026-06-09T22:40:34+00:00

If I have an unsynchronized java collection in a multithreaded environment, and I don’t

  • 0

If I have an unsynchronized java collection in a multithreaded environment, and I don’t want to force readers of the collection to synchronize[1], is a solution where I synchronize the writers and use the atomicity of reference assignment feasible? Something like:

private Collection global = new HashSet(); // start threading after this

void allUpdatesGoThroughHere(Object exampleOperand) {
  // My hypothesis is that this prevents operations in the block being re-ordered
  synchronized(global) {
    Collection copy = new HashSet(global);
    copy.remove(exampleOperand);
    // Given my hypothesis, we should have a fully constructed object here. So a 
    // reader will either get the old or the new Collection, but never an 
    // inconsistent one.
    global = copy;    
  }
}

// Do multithreaded reads here. All reads are done through a reference copy like:
// Collection copy = global;
// for (Object elm: copy) {...
// so the global reference being updated half way through should have no impact 

Rolling your own solution seems to often fail in these type of situations, so I’d be interested in knowing other patterns, collections or libraries I could use to prevent object creation and blocking for my data consumers.


[1] The reasons being a large proportion of time spent in reads compared to writes, combined with the risk of introducing deadlocks.


Edit: A lot of good information in several of the answers and comments, some important points:

  1. A bug was present in the code I posted. Synchronizing on global (a badly named variable) can fail to protect the syncronized block after a swap.
  2. You could fix this by synchronizing on the class (moving the synchronized keyword to the method), but there may be other bugs. A safer and more maintainable solution is to use something from java.util.concurrent.
  3. There is no “eventual consistency guarantee” in the code I posted, one way to make sure that readers do get to see the updates by writers is to use the volatile keyword.
  4. On reflection the general problem that motivated this question was trying to implement lock free reads with locked writes in java, however my (solved) problem was with a collection, which may be unnecessarily confusing for future readers. So in case it is not obvious the code I posted works by allowing one writer at a time to perform edits to “some object” that is being read unprotected by multiple reader threads. Commits of the edit are done through an atomic operation so readers can only get the pre-edit or post-edit “object”. When/if the reader thread gets the update, it cannot occur in the middle of a read as the read is occurring on the old copy of the “object”. A simple solution that had probably been discovered and proved to be broken in some way prior to the availability of better concurrency support in java.
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T22:40:35+00:00Added an answer on June 9, 2026 at 10:40 pm

    Rather than trying to roll out your own solution, why not use a ConcurrentHashMap as your set and just set all the values to some standard value? (A constant like Boolean.TRUE would work well.)

    I think this implementation works well with the many-readers-few-writers scenario. There’s even a constructor that lets you set the expected “concurrency level”.

    Update: Veer has suggested using the Collections.newSetFromMap utility method to turn the ConcurrentHashMap into a Set. Since the method takes a Map<E,Boolean> my guess is that it does the same thing with setting all the values to Boolean.TRUE behind-the-scenes.


    Update: Addressing the poster’s example

    That is probably what I will end up going with, but I am still curious about how my minimalist solution could fail. – MilesHampson

    Your minimalist solution would work just fine with a bit of tweaking. My worry is that, although it’s minimal now, it might get more complicated in the future. It’s hard to remember all of the conditions you assume when making something thread-safe—especially if you’re coming back to the code weeks/months/years later to make a seemingly insignificant tweak. If the ConcurrentHashMap does everything you need with sufficient performance then why not use that instead? All the nasty concurrency details are encapsulated away and even 6-months-from-now you will have a hard time messing it up!

    You do need at least one tweak before your current solution will work. As has already been pointed out, you should probably add the volatile modifier to global‘s declaration. I don’t know if you have a C/C++ background, but I was very surprised when I learned that the semantics of volatile in Java are actually much more complicated than in C. If you’re planning on doing a lot of concurrent programming in Java then it’d be a good idea to familiarize yourself with the basics of the Java memory model. If you don’t make the reference to global a volatile reference then it’s possible that no thread will ever see any changes to the value of global until they try to update it, at which point entering the synchronized block will flush the local cache and get the updated reference value.

    However, even with the addition of volatile there’s still a huge problem. Here’s a problem scenario with two threads:

    1. We begin with the empty set, or global={}. Threads A and B both have this value in their thread-local cached memory.
    2. Thread A obtains obtains the synchronized lock on global and starts the update by making a copy of global and adding the new key to the set.
    3. While Thread A is still inside the synchronized block, Thread B reads its local value of global onto the stack and tries to enter the synchronized block. Since Thread A is currently inside the monitor Thread B blocks.
    4. Thread A completes the update by setting the reference and exiting the monitor, resulting in global={1}.
    5. Thread B is now able to enter the monitor and makes a copy of the global={1} set.
    6. Thread A decides to make another update, reads in its local global reference and tries to enter the synchronized block. Since Thread B currently holds the lock on {} there is no lock on {1} and Thread A successfully enters the monitor!
    7. Thread A also makes a copy of {1} for purposes of updating.

    Now Threads A and B are both inside the synchronized block and they have identical copies of the global={1} set. This means that one of their updates will be lost! This situation is caused by the fact that you’re synchronizing on an object stored in a reference that you’re updating inside your synchronized block. You should always be very careful which objects you use to synchronize. You can fix this problem by adding a new variable to act as the lock:

    private volatile Collection global = new HashSet(); // start threading after this
    private final Object globalLock = new Object(); // final reference used for synchronization
    
    void allUpdatesGoThroughHere(Object exampleOperand) {
      // My hypothesis is that this prevents operations in the block being re-ordered
      synchronized(globalLock) {
        Collection copy = new HashSet(global);
        copy.remove(exampleOperand);
        // Given my hypothesis, we should have a fully constructed object here. So a 
        // reader will either get the old or the new Collection, but never an 
        // inconsistent one.
        global = copy;    
      }
    }
    

    This bug was insidious enough that none of the other answers have addressed it yet. It’s these kinds of crazy concurrency details that cause me to recommend using something from the already-debugged java.util.concurrent library rather than trying to put something together yourself. I think the above solution would work—but how easy would it be to screw it up again? This would be so much easier:

    private final Set<Object> global = Collections.newSetFromMap(new ConcurrentHashMap<Object,Boolean>());
    

    Since the reference is final you don’t need to worry about threads using stale references, and since the ConcurrentHashMap handles all the nasty memory model issues internally you don’t have to worry about all the nasty details of monitors and memory barriers!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Have an issue with marshall and unmarshall readers and writers. So here it is.
Assume we have a multithreaded C program (pthreads), and the (unsynchronized) shared variable accesses
Have finally got a responsive site working (of a fashion). What I want to
I am trying to set the difference between synchronized and unsynchronized methods.. I have
Okay, i have this question in one regarding threads. there are two unsynchronized threads
We have few components in our project extending HashMap . Due to unsynchronized access
I have an parent class, and several child classes. What I want is when
Have an app that can use tts to read text messages. It can also
I want to write documentation on my pet project. I have 30 tables and
Have you guys had any experiences (positive or negative) by placing your source code/solution

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.