C#中Thread.Equals与ManagedThreadId对比:二者结果是否可能不一致?
关于Thread.Equals与ManagedThreadId对比的疑问解答
好问题!咱们直接针对你的核心疑问来拆解:
对于同一个活跃的托管线程,绝对不会出现Thread.Equals返回false但ManagedThreadId对比为true的情况。原因如下:
1. Thread.Equals的判断逻辑
.NET中的Thread.Equals方法重写了默认的引用相等判断,它实际比较的是两个Thread对象是否关联到同一个底层操作系统线程。只要两个Thread实例指向的是同一个存活的托管线程,Equals就会返回true——不管这两个实例是通过Thread.CurrentThread获取的,还是从字典里取出的缓存实例。
2. ManagedThreadId的特性
每个活跃的托管线程都会被CLR分配一个唯一的ManagedThreadId,这个ID在线程的整个生命周期内是固定不变的,而且不会被其他正在运行的线程复用。只有当某个线程完全终止后,CLR才可能把这个ID重新分配给新创建的线程,但此时的新线程已经是完全不同的线程了,并非你所说的“同一个线程”。
3. 两种判断方式的一致性(针对同一线程)
只要你要判断的两个Thread对象对应的是同一个活跃线程:
Thread.CurrentThread.Equals(dictionary[id].OwnerThread)返回true时,Thread.CurrentThread.ManagedThreadId == dictionary[id].OwnerThread.ManagedThreadId必然也为true;- 反过来,ID相等也意味着
Equals一定会返回true,因为同一个活跃线程的ID唯一且对应同一个OS线程。
潜在的注意点
需要提醒的是:如果字典中保存的OwnerThread是已经终止的线程,此时可能出现新线程复用了旧线程的ManagedThreadId的情况——这时候ID对比会返回true,但Thread.Equals会返回false(因为两者是不同的OS线程)。但这种场景下,旧线程已经终止,显然不可能是当前线程,所以如果你的业务逻辑会保证字典中只保留活跃线程的引用,那用ManagedThreadId替换Equals是完全安全的。
内容的提问来源于stack exchange,提问作者Vargan
相关产品推荐
相关产品推荐

