我的问题是,如果我有时在同一个字符串上使用多线程
字符串不会被替换。(我在记事本上写了这个,所以语法可能是
错误的)
使用System.Thread ...其他当然
class ....
{
private static StringBuild container = new StringBuilder();
static void Main(...)
{
container.Append(Read From File(Kind of long));
Thread thread1 = new Thread(Function1);
Thread thread2 = new Thread(Function2);
thread1.Start();
thread2.Start();
//Print out container
}
static void Function1
{
//Do calculation and stuff to get the Array for the foreach
foreach (.......Long loop........)
{
container.Replace("this", "With this")
}
}
//Same goes for function but replacing different things.
static void Function2
{
//Do calculation and stuff to get the Array for the foreach
foreach (.......Long loop........)
{
container.Replace("this", "With this")
}
}
}
现在有时某些元素无法替换。 所以我的解决方案是在另一个
上调用container.Replace方法并做一个“锁定”哪个有效,但这是正确的方法吗?
private class ModiflyString
{
public void Do(string x, string y)
{
lock (this)
{
fileInput.Replace(x, y);
}
}
}
答案 0 :(得分:5)
你应该锁定StringBuilder对象本身(在替换函数内):
lock (container)
{
container.Replace("this", "With this");
}
或创建一个单独的锁定对象:
static object _stringLock = new object();
...
lock(stringLock)
{
container.Replace("this", "With this");
}
答案 1 :(得分:3)
当您创建多个ModifyString对象并且我猜你这样做时,你的锁定将不起作用。
简单版本:
public void Do(string x, string y)
{
lock (fileInput)
{
fileInput.Replace(x, y);
}
}
最好创建一个单独的对象来进行锁定,但上面更好地说明了原则:所有竞争线程都应该锁定在同一个对象上。
标准方法如下:
private static StringBuild container = new StringBuilder();
private static object syncLock = new object(); // simple object, 1-1 with container
然后你可以(线程)安全地使用:
lock(syncLock)
{
container.Replace(...);
}
答案 2 :(得分:2)
只要两个线程具有相同的ModifyString类实例,那就可以正常工作。换句话说,这将起作用,因为对“this”的锁定必须是对同一实例的锁定:
class Blah
{
private static StringBuild container = new StringBuilder();
private static ModifyString modifyString = new ModifyString();
static void Main(...)
{
container.Append(Read From File(Kind of long));
Thread thread1 = new Thread(Function1);
Thread thread2 = new Thread(Function2);
thread1.Start();
thread2.Start();
//Print out container
}
static void Function1
{
//Do calculation and stuff to get the Array for the foreach
foreach (.......Long loop........)
{
modifyString.Do("this", "With this")
}
}
//Same goes for function but replacing different things.
static void Function2
{
//Do calculation and stuff to get the Array for the foreach
foreach (.......Long loop........)
{
modifyString.Do("this", "With this")
}
}
}
如果您执行以下操作,它将 NOT 工作,因为lock(this)不起作用,因为它们是两个单独的实例:
class Blah
{
private static StringBuild container = new StringBuilder();
static void Main(...)
{
container.Append(Read From File(Kind of long));
Thread thread1 = new Thread(Function1);
Thread thread2 = new Thread(Function2);
thread1.Start();
thread2.Start();
//Print out container
}
static void Function1
{
ModifyString modifyString = new ModifyString();
//Do calculation and stuff to get the Array for the foreach
foreach (.......Long loop........)
{
modifyString.Do("this", "With this")
}
}
//Same goes for function but replacing different things.
static void Function2
{
ModifyString modifyString = new ModifyString();
//Do calculation and stuff to get the Array for the foreach
foreach (.......Long loop........)
{
modifyString.Do("this", "With this")
}
}
}
有些人实际上会创建一个“虚拟”对象来执行锁定,而不是使用“this”(你不能锁定字符串,因为它是一个值类型)。