멀티 스레드를 사용하여 동일한 문자열 (StringBuilder)에 액세스합니다
-
13-09-2019 - |
문제
내 문제는 언젠가 같은 문자열에서 멀티 스레드를 사용하는 것입니다.
문자열은 대체되지 않습니다. (나는 이것을 메모장에 썼으므로 구문이
잘못된)
System을 사용하여 스레드 ... 다른 사람의 다른 사람들
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")
}
}
}
이제 언젠가는 일부 요소가 교체되지 않습니다. 그래서 이것에 대한 나의 해결책은 컨테이너를 호출하는 것입니다.
방법과 "잠금"을 수행하지만 어느 것이 작동하지만 올바른 방법입니까?
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
그런 다음 안전하게 사용할 수 있습니다.
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")
}
}
}
어떤 사람들은 실제로 "this"를 사용하는 대신 잠금 장치를 수행하기 위해 "더미"객체를 만들 것입니다 (값 유형이기 때문에 문자열을 잠글 수 없습니다).
제휴하지 않습니다 StackOverflow