- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
System.Threading.Interlocked.CompareExchange
运算符提供比较和交换操作的原子(因此线程安全)C# 实现。
例如int i = 5; Interlocked.CompareExchange(ref i, 10, 5);
执行此命令后,int i 的值 = 10。并且比较和交换以原子方式发生(单个操作)。
当我尝试将它与类实例一起使用时,比较失败并且没有交换值。
public class X
{
public int y;
public X(int val) { y = val; }
}
当我这样做的时候
X a = new X(1);
X b = new X(1);
X c = new X(2);
Interlocked.CompareExchange<X>(ref a, c, b);
比较和交换操作失败。因此,我将类 X 的等于和 == 运算符重写为
public override bool Equals(object obj) { return y == ((X) obj).y; }
所以,现在我得到 Interlocked.Equals(a,b)
为 true
,但是 CompareExchange
操作仍然失败。
有什么方法可以做到吗?我想比较两个类实例并根据比较结果为其中之一赋值。
最佳答案
没有。这是不可能的。
Interlocked.CompareExchange
基本上直接映射到能够自动比较和交换内存地址内容的汇编指令。我相信在 32 位模式下,指令的 64 位版本可用(以及 32 位和 16 位版本),而在 64 位模式下,我认为 128 位版本可用。但仅此而已。 CPU 没有“基于其特定 Equals
函数的交换 .NET 类”指令。
如果你想交换任意对象,使用任意相等函数,你必须自己做,使用锁或其他同步机制。
有an overload Interlocked.CompareExchange
函数适用于对象引用,但出于上述原因,它使用了引用相等性。它只是比较引用,然后交换它们。
针对您的评论,使用结构并不能解决问题。同样,CPU 只能原子地比较和交换某些固定大小的值,并且它没有抽象数据类型的概念。可以使用引用类型,因为引用本身具有有效大小,并且可以由 CPU 与另一个引用进行比较。但是 CPU 对引用指向的对象一无所知。
关于c# - 将 Interlocked.CompareExchange 与类一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6690386/
Interlocked.CompareExchange() 方法 ( docs ) 粗略地说: “我有一个变量,我想我知道它当前有什么值。如果我是对的,请将值更改为那个”。 关键是这个方法可以用来在多
伙计们, 我希望您评估下面的下一个代码。如您所见,我使用 Interlocked.CompareExchange,在这种情况下有意义吗? (我不确定它是否正确)。 如果有任何注释、评论等,我将很高兴。
我的目标是: 有一定范围的整数,我必须测试该范围内的每个整数是否随机。我想为此使用多个线程,并使用共享计数器在线程之间平均分配工作。我将计数器设置为初始值,让每个线程取一个数,增加它,进行一些计算,然
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Interlocked.CompareExchange using GreaterThan or LessT
我想知道是否有可能将以下代码中的初始值重新排序为在计算之后导致未定义的行为。 以下例子摘自https://learn.microsoft.com/en-us/dotnet/api/system.thr
以下语句(寻址与第一个和第三个参数相同的变量)是否总是会导致变量 b 在完成时获取变量 c 的值,或者另一个线程是否有可能在获取参数时更改一个或多个参数在比较操作期间导致第一个和第三个参数包含不同的值
编译器或处理器能否重新排序以下指令,以便另一个线程看到 a == 0 和 b == 1? 假设 int a = 0, b = 0; 某处。 System.Threading.Interlocked.C
我遇到了 .NET 3.5 的 ConcurrentDictionary 实现(很抱歉我现在可以找到链接),它使用这种锁定方法: var current = Thread.CurrentThread.
我正在尝试使用 Interlocked.CompareExchange使用此枚举: public enum State { Idle, Running, //... } 以下代
我正在阅读 Joe Duffy 关于 Volatile reads and writes, and timeliness 的帖子,我正在尝试了解帖子中最后一个代码示例的一些内容: while (Int
假设你有一个属性public Foo Bar { get; } 你想延迟初始化。一种这样的方法可能是使用 Interlocked 类,它保证某些操作序列(例如递增、添加、比较交换)的原子性。你可以这样
我需要递增一个计数器直到它达到一个特定的数字。我可以使用两个并行任务来增加数字。我没有使用锁来检查数字是否未达到最大允许值然后递增,而是使用 Interlocked .CompareExchange
System.Threading.Interlocked.CompareExchange 运算符提供比较和交换操作的原子(因此线程安全)C# 实现。 例如int i = 5; Interlocked.
以下示例来自 MSDN . public class ThreadSafe { // Field totalValue contains a running total that can be
using System; using System.Threading; using System.Threading.Tasks; namespace _1._41_Compare_and_Exc
我有一个整数数组,用于跟踪 10,000 个并发任务的完成情况,其中值为 1 或 0。我认为如果这个数组是一个位数组并且每个并发线程都使用 interlocked 会更有效率。CompareExcha
来自 https://msdn.microsoft.com/en-us/library/bb297966(v=vs.110).aspx [ComVisibleAttribute(false)] pub
免责声明:我的帖子显然总是很冗长。如果您碰巧知道标题问题的答案,请随意回答,而无需阅读我下面的扩展讨论。 System.Threading.Interlocked类提供了一些非常有用的方法来帮助编写线
概要: 在我看来,这: 将表示逻辑状态的字段包装到单个不可变的消耗对象中 通过调用Interlocked.CompareExchange 更新对象的权威引用 并适当地处理更新失败 提供了一种并发性,不
在Link.TryAdd方法的dapper代码中,有如下一段代码: var snapshot = Interlocked.CompareExchange(ref head, null, null);
我是一名优秀的程序员,十分优秀!