何时使用atomic.LoadPointer

What is the difference between using atomic.StorePointer / LoadPointer:

data := "abc"
atomic.StorePointer(&p, unsafe.Pointer(&data))
fmt.Printf("value is %s
", *(*string)(atomic.LoadPointer(&p)))

And just using using the pointer normally?

data := "abc"
p = unsafe.Pointer(&data)
fmt.Printf("value is %s
", *(*string)(p))

What could go wrong if I decide to just read from a pointer like in the second example, instead of using LoadPointer? I can guess there might be some kind of race, but practically, what could actually go wrong?

Some examples:

As long as you only have one goroutine accessing the value, nothing will go wrong. As soon as you have several goroutines, you need atomic access in order to read/write the latest value (not the possibly stale value that is in your CPU cache).