在我的上一个问题之后,我尝试修复代码,但输出仍然不是我所期望的。我尝试定义一个线程安全整数:
using System;
using System.Threading;
public struct SInt
{
private int _value;
public SInt(int initialValue = 0)
{
_value = initialValue;
}
public int Value => Volatile.Read(ref _value); // Interlocked.CompareExchange(ref _value, 0, 0);
// Add a value
public int Add(int value) => Interlocked.Add(ref _value, value);
// Subtract a value
public int Subtract(int value) => Interlocked.Add(ref _value, -value);
// Multiply the value
public int Multiply(int value)
{
int initial, computed;
do
{
initial = Value;
computed = initial * value;
}
while (Interlocked.CompareExchange(ref _value, computed, initial) != initial);
return computed;
}
// Divide the value
public int Divide(int value)
{
if (value == 0)
throw new DivideByZeroException();
int initial, computed;
do
{
initial = Value;
computed = initial / value;
}
while (Interlocked.CompareExchange(ref _value, computed, initial) != initial);
return computed;
}
// Increment the value
public int Increment() => Interlocked.Increment(ref _value);
// Decrement the value
public int Decrement() => Interlocked.Decrement(ref _value);
// Overloaded operators
public static SInt operator +(SInt a, int b)
{
a.Add(b);
return a;
}
public static SInt operator -(SInt a, int b)
{
a.Subtract(b);
return a;
}
public static SInt operator *(SInt a, int b)
{
a.Multiply(b);
return a;
}
public static SInt operator /(SInt a, int b)
{
a.Divide(b);
return a;
}
public static SInt operator ++(SInt a)
{
a.Increment();
return a;
}
public static SInt operator --(SInt a)
{
a.Decrement();
return a;
}
// Equality operators
public static bool operator ==(SInt a, SInt b) => a.Value == b.Value;
public static bool operator !=(SInt a, SInt b) => a.Value != b.Value;
// Comparison operators
public static bool operator <(SInt a, SInt b) => a.Value < b.Value;
public static bool operator <=(SInt a, SInt b) => a.Value <= b.Value;
public static bool operator >(SInt a, SInt b) => a.Value > b.Value;
public static bool operator >=(SInt a, SInt b) => a.Value >= b.Value;
// Implicit conversion from int to SInt
public static implicit operator SInt(int value) => new SInt(value);
// Implicit conversion from SInt to int
public static implicit operator int(SInt sInt) => sInt.Value;
public override bool Equals(object? obj)
{
if (obj is SInt other)
{
return this == other;
}
return false;
}
public override int GetHashCode() => Value.GetHashCode();
public override string ToString() => Value.ToString();
}
然后我重写了程序:
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main(string[] args)
{
List<Thread> threads = new List<Thread>();
SInt s = 0;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i <1000; i++)
{
var t = new Thread(() =>
{
s++;
Thread.Sleep(1000);
});
t.Priority = ThreadPriority.Highest;
threads.Add(t);
t.Start();
}
foreach (var t in threads)
t.Join();
stopwatch.Stop();
Console.WriteLine($"Time: {stopwatch.ElapsedMilliseconds / 1000.0} Seconds");
Console.WriteLine(s);
Console.WriteLine(threads.Count(t => t.ThreadState == System.Threading.ThreadState.Stopped));
Console.ReadKey();
}
}
我的笔记本电脑中的输出:
Time: 85.16 Seconds
989
1000
我预计 989 是 1000。
怎么了?
在 C# 中,
struct
是值类型。
因此您将其退回的地方,例如在:
public static SInt operator ++(SInt a)
{
a.Increment();
return a;
}
您实际上归还了一份副本。
如果
SInt
是一个类,它的行为会像您期望的那样,返回对当前实例的引用。