2011-10-12 11 views
1

私がWebアプリケーションでたくさん使っているスタティックヘルパークラスがあるとします。アプリが1秒間に約20件のリクエストを受信し、魔法によって静的クラスに正確に同じナノ秒で何か作業を依頼するとします。静的クラスと複数の同時リクエスト

この場合、どうなりますか?

いくつかのコンテキストを提供するために、クラスはLinq-to-SQLクエリを実行するために使用されます。ユーザーIDを含むいくつかのパラメータを受け取り、カスタムオブジェクトのリストを返します。

ありがとうございました。

+3

止められない力が停止し、不動のオブジェクトが移動 – BrokenGlass

答えて

3

この場合、どうなりますか?

あなたのメソッドがreentrantである場合、スレッドセーフであり、起こることは、それらが動作する可能性があるということです。これらの静的メソッドがいくつかの共有状態に依存し、この状態へのアクセスを同期していない場合、この共有状態は破損する可能性があります。しかし、同じナノ秒でメソッドをヒットする必要はありません。あなたがそれを同期しないと、2は十分に十分です。

スタティックメソッド自体は悪くありません(実は、単体テストには向いていませんが、それは別のトピックです)。マルチスレッド環境では、それらが実装されている方法です。だから、それらをスレッドセーフにする必要があります。


UPDATE:コメント欄にあなたがいる限り、静的な方法で使用されるすべての変数がローカルであるとしてLINQ-TO-SQLを言及しているので、このメソッドはスレッドセーフである

。読み込みと書き込みについては何も言っ

public static SomeEntity GetEntity(int id) 
{ 
    using (var db = new SomeDbContext()) 
    { 
     return db.SomeEntities.FirstOrDefault(x => x.Id == id); 
    } 
} 
+0

静的クラスは、linq-to-sqlクエリに使用されます。悪いアイデア? – frenchie

+0

@frenchieこの静的クラスがスレッドセーフではない静的リソースに依存しない限り、あなたはうまくいくはずです。 –

+0

@frenchie、Linq-To-SQLで使用できるスレッドセーフメソッドの例を提供するために私の答えを更新しました。 –

0

それは(あなたが状態を共有するためにこれをやっている場合)、Webアプリケーションでこれを行うことを避ける...またはalternativly /ロックで読み書き保護する厄介な方法で実施クラッシュ:

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

しかし正直なところ、あなたが本当に必要な場合を除いて、本当にスタティックスを使用するのは避けなければなりません。本当にロック戦略に非常に注意しなければならない場合、破壊をテストして、

+0

:たとえば?これが*共有状態を使用しているという証拠はありません。 –

+0

@ジョン:仮定は危険なことです;私はOPがこれをスレッド間で状態を共有するために行っていると仮定していました。あなたのコメントを投稿したのと同様にこれを反映するように投稿を更新しました。 – JonAlb

2

メソッドがスレッドセーフであることを確認する必要があります。したがって、静的属性あらゆる種類の状態を保存するためのものです。静的メソッド内で新しいオブジェクトを宣言している場合は、各スレッドに独自のオブジェクトがあるため、問題はありません。

+0

スレッドセーフは何を意味しますか? – frenchie

+0

複数のスレッドが同時にメソッドを実行する場合、共有リソースへのアクセスが制御されていることを確認する必要があります。そうしないと予期しない動作が発生します。これはスレッドセーフな用語のソートレジュームです。 –

5

それはあなたの「何らかの仕事」が何を意味するかによってまったく異なります。共有状態に関係しない場合、それは絶対にうまくいきます。共有状態にアクセスする必要がある場合は、スレッドセーフな方法でそれを処理する方法を検討する必要があります。

親指の一般的なルールは、クラスの公開APIは、スレッドセーフな静的メソッドのためでなければならないことですが、スレッドセーフインスタンスメソッドのためである必要はありません - いずれかのインスタンスは、単一の内で使用される一般的糸。もちろん、あなたのクラスが何をしているかによって異なります。what you mean by thread-safe

+0

私はこのクラスをlinq-to-sqlクエリに使用しています。それは悪い考えですか?クラスは静的でなく、使用するたびにインスタンス化されるべきですか? – frenchie

+0

@frenchie:それはかなり曖昧な言葉です - リンクされたブログ記事を読んでください。しかし、何らかの特定の状況の中で、複数のスレッドが同じコードを同時に呼び出すと、悪いことは起こらないという意味です。 –

+1

@frenchie:Linq2SQL DataContext自体はスレッドセーフではありません。各ヘルパー呼び出しが独自のコンテキストを初期化し、静的に共有されている他のリソースにアクセスしていない場合は、 –

1

静的クラスに状態があるかどうか(つまり、すべての呼び出しで共有される静的変数)によって異なります。それがなければ、それはいいです。そうであれば、それは良くありません。例:

// Fine 
static class Whatever 
{ 
    public string DoSomething() { 
     return "something"; 
    } 
} 

// Death from above 
static class WhateverUnsafe 
{ 
    static int count = 0; 
    public int Count() { 
     return ++count; 
    } 
} 

ロックを使用して2番目の作業を正常にすることはできますが、デッドロックと並行性の問題が発生します。

私は静的クラスを持つ大量のWebアプリケーションを構築しましたが、共有状態は決してありません。

+0

Ok;私はlinq - SQLクエリの静的クラスを使用しています。私はこれをしたらどうなるのだろう?クラスを静的に保つことを考えていたので、オブジェクトをインスタンス化するコストを節約しました。 – frenchie

+0

オブジェクトのインスタンス化のコストについて心配する必要はないでしょうか。 Linq2Sqlがスレッドセーフであるかどうかはわかりません。 – Deleted

関連する問題