vb,net 多个线程读取同一个静态会合为什么不发生任何冲突和死销
vb,net 多个线程读取同一个静态集合为什么不发生任何冲突和死销?
多个线程同时读取同一个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.",所以仅仅对它并发读没有问题。
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.",所以仅仅对它并发读没有问题。