Reading this question, I wanted to test if I could demonstrate the non-atomicity of reads and writes on a type for which the atomicity of such operations is not guaranteed.
You might try getting rid of the 'dCopy = _d' and simply use _d in your assert.
That way two threads are reading/writing to the same variable at the same time.
Your current version makes a copy of _d which creates a new instance, all in the same thread, which is a thread safe operation:
http://msdn.microsoft.com/en-us/library/system.double.aspx
All members of this type are thread safe. Members that appear to modify instance state actually return a new instance initialized with the new value. As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety.
However if both threads are reading/writing to the same variable instance then:
http://msdn.microsoft.com/en-us/library/system.double.aspx
Assigning an instance of this type is not thread safe on all hardware platforms because the binary representation of that instance might be too large to assign in a single atomic operation.
Thus if both threads are reading/writing to the same variable instance you would need a lock to protect it (or Interlocked.Read/Increment/Exchange., not sure if that works on doubles)
Edit
As pointed out by others, on an Intel CPU reading/writing a double is an atomic operation. However, if the program is compiled for X86 and uses a 64 bit integer data type, then the operation would not be atomic. As demonstrated in the following program. Replace the Int64 with double and it appears to work.
Public Const ThreadCount As Integer = 2
Public thrdsWrite() As Threading.Thread = New Threading.Thread(ThreadCount - 1) {}
Public thrdsRead() As Threading.Thread = New Threading.Thread(ThreadCount - 1) {}
Public d As Int64
_
Sub Main()
For i As Integer = 0 To thrdsWrite.Length - 1
thrdsWrite(i) = New Threading.Thread(AddressOf Write)
thrdsWrite(i).SetApartmentState(Threading.ApartmentState.STA)
thrdsWrite(i).IsBackground = True
thrdsWrite(i).Start()
thrdsRead(i) = New Threading.Thread(AddressOf Read)
thrdsRead(i).SetApartmentState(Threading.ApartmentState.STA)
thrdsRead(i).IsBackground = True
thrdsRead(i).Start()
Next
Console.ReadKey()
End Sub
Public Sub Write()
Dim rnd As New Random(DateTime.Now.Millisecond)
While True
d = If(rnd.Next(2) = 0, 0, Int64.MaxValue)
End While
End Sub
Public Sub Read()
While True
Dim dc As Int64 = d
If (dc <> 0) And (dc <> Int64.MaxValue) Then
Console.WriteLine(dc)
End If
End While
End Sub