Java has a segmented concurrent hash map, see  java - In ConcurrentHashMap 
how the segments are defined - Stack Overflow 
<https://stackoverflow.com/questions/39997574/in-concurrenthashmap-how-the-segments-are-defined>
 where 
each segment is thread safe. So you when values of keys in different 
segments are accessed access can happen concurrently which improves 
throughput.

On Wednesday, July 29, 2026 at 7:32:35 AM UTC+2 Touring Tim wrote:

> I'm sure you should put a lock if changing v, I have similar maps and 
> always lock when writing to it and rlock when reading.
>
> For me a completely static map initialised and k,v set, is one that needs 
> no lock to read concurrently.
>
> On Wed, 29 Jul 2026, 06:35 'robert engels' via golang-nuts, <
> [email protected]> wrote:
>
>> That code is correct, and matches the OPs scenario, but it goes beyond 
>> your original constraints which was that they “are not concurrently written 
>> to”. With that code, you are also synchronizing any reads with the mutators 
>> - which is what I was trying to clarify. 
>>
>> > On Jul 28, 2026, at 11:19 PM, Ian Lance Taylor <[email protected]> 
>> wrote:
>> > 
>> > On Tue, Jul 28, 2026 at 7:50 PM robert engels <[email protected]> wrote:
>> >> 
>> >> I don’t think that is true. You still need to use atomics or locks to 
>> modify the values even with a single writer, or there’s no guarantee a 
>> reader will see the updated value ever.
>> > 
>> > What I mean is that it is OK to write this:
>> > 
>> > https://go.dev/play/p/Mw7lP7ElPQ_a
>> > 
>> > package main
>> > 
>> > import (
>> >    "fmt"
>> >    "sync"
>> > )
>> > 
>> > func main() {
>> >    m := map[string]*int{
>> >        "a": new(1),
>> >        "b": new(2),
>> >    }
>> >    var wg sync.WaitGroup
>> >    for k := range m {
>> >        wg.Go(func() {
>> >            (*m[k])++
>> >        })
>> >    }
>> >    wg.Wait()
>> >    for k, v := range m {
>> >        fmt.Println(k, *v)
>> >    }
>> > }
>> > 
>> > 
>> > Ian
>> > 
>> >>>> On Jul 28, 2026, at 3:04 PM, Ian Lance Taylor <[email protected]> 
>> wrote:
>> >>> 
>> >>> On Tue, Jul 28, 2026 at 9:15 AM '[email protected]' via 
>> golang-nuts
>> >>> <[email protected]> wrote:
>> >>>> 
>> >>>> (I posted this to r/golang but I didn't get what I consider a 
>> definitive answer).
>> >>>> 
>> >>>> I know that maps aren't safe for concurrent access, but I've always 
>> thought this meant only that you can't add or delete keys concurrently.
>> >>>> 
>> >>>> Let's say I already have a map[string]int that has been filled with 
>> keys that are file names. I won't be adding any more keys. I want to add an 
>> int value for each existing key to contain the file size. Could I do this 
>> by running a bunch of go routines, one per file name key? (Let's ignore for 
>> now whether doing this would be any faster than not using go routines.)
>> >>>> 
>> >>>> The Go Language spec doesn't directly define the rules for 
>> concurrent memory safety. Instead, those rules are explicitly defined in 
>> the Go Memory Model (https://go.dev/ref/mem). I looked there but I 
>> wasn't able to find what I was looking for.  The Go FAQ has a section on 
>> Atomic Maps (https://go.dev/doc/faq#atomic_maps) says
>> >>>> 
>> >>>> "As long as all goroutines are only reading—looking up elements in 
>> the map, including iterating through it using a for range loop—and not 
>> changing the map by assigning to elements or doing deletions, it is safe 
>> for them to access the map concurrently without synchronization."
>> >>>> 
>> >>>> The question here is what is meant by "assigning to elements".
>> >>>> 
>> >>>> My thinking is that this should be allowed because adding a file 
>> name to the map should have also added space for an int value. So, I'd just 
>> be modifying this int, and not changing the hash table data structure. Is 
>> this correct?
>> >>> 
>> >>> The Go memory model prohibits concurrent reads and writes, or
>> >>> concurrent writes, to variables. A map is a variable. You can't
>> >>> concurrently modify either the key or the value of a map.
>> >>> 
>> >>> What you can do is store a pointer in the map. Then you can modify the
>> >>> fields to which that pointer points as you wish. Of course you have to
>> >>> avoid concurrent modifications of those memory locations, but that
>> >>> doesn't matter if each element is only modified by a single goroutine.
>> >>> 
>> >>> Ian
>> >>> 
>> >>> --
>> >>> You received this message because you are subscribed to the Google 
>> Groups "golang-nuts" group.
>> >>> To unsubscribe from this group and stop receiving emails from it, 
>> send an email to [email protected].
>> >>> To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/CAOyqgcXoVnqDhF2n5rYMPACpLZmwWROt%3DQCAkVXRqucnj4D%3D4w%40mail.gmail.com
>> .
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected].
>>
> To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/533BF668-A19F-47E7-BDA0-4898A7DBBA03%40me.com
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/72689552-17bf-4c81-b37a-4e34e1aa6e59n%40googlegroups.com.

Reply via email to