vb,net 多个线程读取同一个静态会合为什么不发生任何冲突和死销

vb,net 多个线程读取同一个静态集合为什么不发生任何冲突和死销?

Shared List3 As New List(Of Integer)(System.Linq.Enumerable.Range(1, 1001))
 Shared List4 As New List(Of Integer)
Shared List5 As New List(Of Integer)


    Shared Sub MySub1()

        For index As Integer = 0 To 1000
           
            List4.Add(List3.MyFunc(index))
        Next
    End Sub

 Shared Sub MySub2()

        For index = 0 To 1000
            List5.Add(List3.MyFunc(index))
        Next

    End Sub


多个线程同时读取同一个List3集合时为什么不发生争抢和死销及冲突呢。

只要写入操作时才发生呢。
------解决思路----------------------
读不改变状态,线程在任何地方打断、再恢复,没有任何问题,无需控制,所以没有冲突。
写会改变状态,比如线程在遍历节点时,正好遍历完第3个将要遍历第4个的时候中断了,恢复过来后:可能第2个位置插入了一个节点,原第3变成了第4,那么继续遍历等于将原第3重新遍历了一次;也可能第2个位置删除了一个节点,原第4变成了第3,那么继续遍历等于将原第4漏过了遍历……
各种情况太复杂,所以只要有了变动,就认为有冲突出错。
------解决思路----------------------
多线程并发写一块内存不是会出现内存错误,而是由于执行顺序不可控导致的结果不确定。比如n个线程并发对一个int变量做自增操作,并不会有任何异常,只是因为没有同步,导致最终结果可能不是n个顺序操作的累加。把这种现象叫做“内存错误”不太合适。

单纯对内存的读写比较简单,但是往往我们不是直接读写内存,而是使用一些类间接的读写,这时候就会涉及类的内部状态,情况更复杂点。

能够说是错误的是对不是线程安全的方法进行并发调用,导致所在类的内部状态混乱,就可能出现异常或错误。理论上只要文档没有明确说明一个属性/方法是线程安全的,都不应该并发调用,无论是读还是写。有些类在读或者使用者认为是读的场景也会更新内部状态,这种并发读也可能导致异常或者错误。

所以是否能够并发读不能自己想当然,必须看文档。像List<T>是文档说明了"It is safe to perform multiple read operations on a List<T>, but issues can occur if the collection is modified while it’s being read.",所以仅仅对它并发读没有问题。