访问使用多线程相同的字符串(StringBuilder的)
-
13-09-2019 - |
题
我的问题是,如果我使用多线程上相同的字符串的某个
该字符串将不会进行更换。(我写了这个记事本上这样的语法可能是
错误的)
使用System.Thread...其他ofcourse
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);
}
}
}
解决方案
您应该锁定StringBuilder对象本身(替换功能内侧):
lock (container)
{
container.Replace("this", "With this");
}
或创建一个单独的锁定对象:
static object _stringLock = new object();
...
lock(stringLock)
{
container.Replace("this", "With this");
}
其他提示
当你创造超过1个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
和然后就可以(thread-)安全地使用:
lock(syncLock)
{
container.Replace(...);
}
这将细只要两个线程具有ModifyString类的同一实例工作。换句话说,这将工作,因为在锁定“本”必须在相同的实例的锁定:
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")
}
}
}
它将不会工作,如果你没了下文,因为锁(这)是行不通的感觉他们是两个不同的实例:
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")
}
}
}
有些人会真正创建一个“虚拟”的对象上,而不是用“这个”执行锁(你不能在线绳锁定,因为它是值类型)。
不隶属于 StackOverflow