我有这样的代码,一些线程将生成字符串(此处为100)并存储到数组,其他单线程将使用索引器[]读取数据并保存到文件。我在 ThreadSafeString 类中使用 Interlocked 类进行字符串交换,但我不知道它是否足以避免死锁和非线程安全问题。我的另一个想法是使用 ConcurrentDirectory<int, string>
确保其安全。
using System;
using System.IO;
using System.Threading;
namespace Test
{
class ThreadSafeString
{
private string _string;
public string Value
{
get => Interlocked.CompareExchange(ref _string, null, null);
set => Interlocked.Exchange(ref _string, value);
}
}
class Program
{
private static readonly ThreadSafeString[] array = new ThreadSafeString[100];
static void Main(string[] args)
{
for (int i = 0; i < 100; i++) array[i] = new ThreadSafeString();
for (int i = 0; i < 100; i++)
{
var thread = new Thread(() =>
{
while (true)
{
string data = "";
//generate data
array[i].Value = data;
Thread.Sleep(100);
}
});
thread.Name = i.ToString();
thread.Start();
}
var ht = new Thread(() =>
{
while (true)
{
for (int i = 0; i < 100; i++)
{
string temp = array[i].Value;
File.WriteAllText(path, temp);
}
Thread.Sleep(2000);
}
});
ht.Start();
Console.ReadKey();
}
}
}
最佳答案
我在这里没有看到 ThreadSafeString 的意义。如果您需要将旧数据作为单个操作进行比较、存储和返回,请使用 Interlocked.CompareExchange
。
Interlocked.CompareExchange(ref _string, null, null);
表示
if (_string == null)
{
_string = null;
return null;
} else return _string;
但作为单个操作。如您所见,它可以轻松替换为
return __string;
与Interlocked.Exchange
相同 - 您不需要对字符串执行此操作:
Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types.
仅当您需要以原子操作的形式获取旧值时,才需要对除此之外的类型执行此操作。
在这里简单地使用 string[]
将具有相同的线程安全性。只要不更改数组大小并对引用类型或单字大小的值类型进行操作,您就可以安全地存储和读取数组中的数据。如果你想读取、更改和存储数据,你只需要担心线程安全,但这是另一个问题,甚至连像 ConcurrentDirectory
关于c# - 多线程数组线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58396341/