0

ロックについて、そしてそれが正しく行われているかどうかについて質問があります。

クラスには、いくつかのメソッドで使用される静的ロックオブジェクトがあります。アクセス修飾子が適切に設定されていると仮定して、簡潔にするためにそれらをリストしません。

class Foo
{ 
   static readonly object MyLock = new object();

   void MethodOne()
   {
       lock(MyLock) { 
          // Dostuff
       }
   }

   void MethodTwo()
   {
       lock(MyLock) { 
          // Dostuff
       }
   }
}

さて、私が理解しているように、ロックは一度に1つのスレッドだけがそれを取得して、1つのメソッドのDoStuff()部分に入ることができることを保証します。

しかし、同じスレッドがMethodOne()とMethodTwo()を同時に呼び出すことは可能ですか?彼が両方の方法で取得したロックを使用しているという意味ですか?

私の意図する機能は、このクラスの他のメソッドが現在実行されていない間、このクラスのすべてのメソッドは単一のスレッドによってのみ呼び出すことができるということです。

基本的な使用法は、単一のエントリと出口ポイントのみが必要なデータベースクラスです。SQL Compactを使用しているため、保護されたデータを読み取ろうとすると、あらゆる種類のメモリエラーが発生します。

データベースでメモリ例外が発生することがあり、それがどこから来ているのかわかりません。1つのスレッドがデータベースで複数のことを実行してから完了するためだと思いましたが、このコードは正常に機能しているようです。

4

4 に答える 4

2

しかし、同じスレッドがMethodOne()とMethodTwo()を同時に呼び出すことは可能ですか?

いいえ。使用されているかどうかに関係なく、同じスレッドで両方のメソッドを同時に呼び出すことはできませlockん。

lock(MyLock) 

それは次のように理解することができます:

MyLockオブジェクトには、それ自体を入力するためのキーがあります。最初にアクセスするスレッド(たとえばt1)がそれを取得します。t1他のスレッドはそれを解放するまで待たなければなりません。ただし、t1別のメソッドを呼び出すことができ、すでにロックを取得しているため、この行を渡します。

しかし、同時に両方のメソッドを呼び出す...シングルスレッドでは不可能です。現在のプログラミングの世界ではありません。

私が理解しているように、ロックは一度に1つのスレッドだけがそれを取得して、1つのメソッドのDoStuff()部分に入ることができることを保証します。

あなたの理解は正しいですが、スレッドは並列実行を行うために使用されますが、スレッド内の実行は常に順次であることに注意してください。

于 2012-11-15T11:30:48.977 に答える
1

しかし、同じスレッドがMethodOne()とMethodTwo()を同時に呼び出すことは可能ですか?

1つのスレッドが同時に何かを呼び出すことはできません。

マルチスレッドアプリケーションでは、これが発生する可能性があります。メソッドは同時に呼び出すことができますが、// Dostuffセクションには順番にしかアクセスできません。

私の意図する機能は、このクラスの他のメソッドが現在実行されていない間、このクラスのすべてのメソッドは単一のスレッドによってのみ呼び出すことができるということです。

次に、アプリケーションで追加のスレッドを使用しないでください。メインのスレッドだけを使用し、追加のスレッドは使用しないでください。

于 2012-11-15T11:30:20.973 に答える
1

Dostuff実行中のスレッドが呼び出す唯一の方法は、MethodOneMethodTwoDostuffMethodOne呼び出すことMethodTwoです。これが発生していない場合(つまり、「相互にロックされた」グループのメソッドが相互に呼び出しない場合)、安全です。

于 2012-11-15T11:31:04.357 に答える
0

ここで答えることができることがいくつかあります。

しかし、同じスレッドがMethodOne()とMethodTwo()を同時に呼び出すことは可能ですか?彼が両方の方法で取得したロックを使用しているという意味ですか?

いいえ、スレッドには、inMethodOne()またはinのいずれかの単一のプログラムカウンターがありますMethodTwo()。ただし、次のような場合は、

public void MethodThree()
{
    lock (MyLock)
    {
        MethodOne();
        MethodTwo();
    }
}

これも機能します。スレッドは同じロックを複数回取得できます。コードがより複雑になると、簡単にデッドロックに陥る可能性があるため、実行していることに注意してください。

私の意図する機能は、このクラスの他のメソッドが現在実行されていない間、このクラスのすべてのメソッドは単一のスレッドによってのみ呼び出すことができるということです。

基本的な使用法は、単一のエントリと出口ポイントのみが必要なデータベースクラスです。SQL Compactを使用しているため、保護されたデータを読み取ろうとすると、あらゆる種類のメモリエラーが発生します。

理由はよくわかりませんが、SqlCompactを使用しているためにこれを行う必要があると思われる場合は、間違っています。SqlCeでサポートされているトランザクションを使用する必要があります。

例えば

using (var connection = new SqlCeConnection())
using (var command = new SqlCeCommand())
using (var transaction = conn.BeginTransaction())
{
    command.Transaction = transaction;
    command.ExecuteNonQuery();
    transaction.Commit();
}
于 2012-11-15T11:43:26.310 に答える