マルチスレッドを使用して、同じ文字列(のStringBuilderを)へのアクセス

StackOverflow https://stackoverflow.com/questions/1268446

  •  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

、その後、あなたは(スレッド)安全に使用することができます:

   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")
        }
    }
}

:あなたが以下を行った場合、ロック(これは)彼らは2つの別々のインスタンスである意味が動作しないので、

これは、 にしないで動作します

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")
        }
    }
}

一部の人々が実際に(それは値型であるので、あなたは文字列をロックすることはできません)「この」を使用しての代わりにロックを実行するために「ダミー」オブジェクトを作成することになります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top