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.
