using System.Runtime.CompilerServices;
using Xunit;
public class ThreadsFeaturesUnitDemos
{
[Fact]
public void SynchronizedObjects()
{
var obj1 = new SynchronizedMethodClass();
var obj2 = new SynchronizedMethodClass();
var obj1HashCode = 0;
var obj2HashCode = 0;
var chars = string.Empty;
const string expectedChars1 = "AAAAABBBBBCCCCCDDDDD";
const string expectedChars2 = "11111222223333344444";
var d = 'A' - '1';
for (char c = 'A'; c <= 'D'; c++)
{
obj1.Count(ref chars, 5, c, out obj1HashCode);
obj2.Count(ref chars, 5, (char)(c - d), out obj2HashCode);
}
var chars1 = string.Concat(chars.Where(c => c >= 'A'));
var chars2 = string.Concat(chars.Where(c => c < 'A'));
Assert.Equal(expectedChars1, chars1);
Assert.Equal(expectedChars2, chars2);
Assert.NotEqual(obj1HashCode, obj2HashCode);
}
public class SynchronizedMethodClass
{
[MethodImpl(MethodImplOptions.Synchronized)]
public void Count(ref string chars, int number, char c, out int thisHashCode)
{
thisHashCode = this.GetHashCode();
for (var i = 0; i < number; i++)
{
Thread.Sleep(50);
chars += c;
}
}
}
}
我期望结果"AA11A1A1........DD5D55D"
。
感谢所有发表评论的人!的确,我应该更加小心)在这个示例中,我想证明同步实例方法仅在一个线程中被阻止,因为被阻止的对象为`this'。
update
public void SynchronizedInstanceMethodsInDifferentThreads()
{
var obj1 = new SynchronizedMethodClass();
var obj2 = new SynchronizedMethodClass();
var chars = new ConcurrentQueue<char>();
const string expectedChars1String = "AAAAABBBBBCCCCCDDDDD";
const string expectedChars2String = "11111222223333344444";
const int charNumber = 5;
var th1 = new Thread(() =>
{
for (char c = 'A'; c <= 'D'; c++)
{
obj1.Count(chars, charNumber, c);
}
});
var th2 = new Thread(() =>
{
for (char c = '1'; c <= '4'; c++)
{
obj2.Count(chars, charNumber, c);
}
});
th1.Start();
th2.Start();
th1.Join();
th2.Join();
var charsString = string.Concat(chars);
var uniqueChars = chars.Distinct();
// Demonstrates that the object being locked is "this".
foreach (var uc in uniqueChars)
{
var ucSeq = new string(uc, charNumber);
Assert.DoesNotContain(ucSeq, charsString);
}
var chars1String = string.Concat(chars.Where(c => c >= 'A'));
var chars2String = string.Concat(chars.Where(c => c < 'A'));
Assert.Equal(expectedChars1String, chars1String);
Assert.Equal(expectedChars2String, chars2String);
}