2013-07-24 9 views
6

Scala、Playフレームワーク、およびMongoDB(ReactiveMongoをドライバとして使用)でWebアプリケーションを構築しています。アプリケーションアーキテクチャは、エンドツーエンドでノンブロッキングです。将来のコードで同期/ロックを使用する

コードの一部では、ScalaのパーサーコンビネータやScalaのリフレクションなど、スレッドセーフではないライブラリにアクセスする必要があります。現在、このような呼び出しは​​ブロックに含まれています。

  1. ​​をfuture-yコードで使用するときは、何か注意が必要ですか?
  2. パフォーマンスとユーザビリティの観点から、​​ではなく、ロック(ReentrantLockなど)を使用する方が良いですか?
+0

「将来のコード」の意味を理解するのに困っています – fge

+0

@fge、コードは「未来」を多用しています。私はそれが文脈(Play、Reactive *など)から十分にはっきりしていると思ったが、そうではなかったようだ。 – missingfaktor

+1

デフォルトの実行コンテキストでブロック操作を実行しないでください。 [この回答](http://stackoverflow.com/a/16834855/406435)が便利かもしれません。 – senia

答えて

2

例:リフレクションと解析は合理的には変更できず、ロックする必要はありませんが、ロックを使用する場合は同期ブロックが行います。私は、同期とロックの使用の間にパフォーマンスの違いがあるとは思わない。

8

)これは古い質問です))例えばusing-actors-instead-of-synchronizedを参照してください。要するに、それがロックするのではなく、役者を使用する方が賢明でしょう:あなたがあなたの代わりにlog.infoの好みのないスレッドセーフなコードを置くことができるように

class GreetingActor extends Actor with ActorLogging { 

    def receive = { 
    case Greeting(who) ⇒ log.info("Hello " + who) 
    } 
} 

1つのメッセージのみが、任意の時点で処理されます、すべて正常に動作します。 BTWでaskパターンを使用すると、先物が必要な既存のコードにアクターをシームレスに統合できます。

+0

あなたは「尋ねる模様」が何であるか、それをどのように使いこなすかを詳しく教えてください。 – missingfaktor

+1

公式の文書http://doc.akkaよりもうまくできませんでした。io/docs/akka/snapshot/scala/actors.html#Ask__受信と受信の未来 – vitalii

3

私の主な問題は、コードの同期セクションまたはロックされたセクションへの呼び出しがブロックされ、実行コンテキストのスレッドが麻痺することです。この問題を回避するには、scala.concurrent.blockingを使用して潜在的にブロックする方法に任意の呼び出しをラップすることができます:

もちろん
import scala.concurrent._ 
import ExecutionContext.Implicits.global 

def synchronizedMethod(s: String) = synchronized{ s.size } 

val f = future{ 
    println("Hello") 
    val i = blocking{ //Adjust the execution context behavior 
    synchronizedMethod("Hello") 
    } 
    println(i) 
    i 
} 

が、俳優の内部のシリアルコードをスレッドローカル変数やラッピングの呼び出しのような代替案を検討した方が良いかもしれません。

最後に、ロックの代わりに同期を使用することをお勧めします。ほとんどのアプリケーション(特にクリティカルセクションが大きい場合)では、パフォーマンスの違いは目立たない。

+1

+1のブロック()の先端です。ロックポーリング、タイムアウト、割り込みなどを利用しない限り、 'synchronized'を使用することで合意しました。 – sourcedelica

2

まあ、私は最も簡単で安全な方法は(もしあなたができるなら)からだと思います。。 すなわち、各スレッドはパーサーコンビネータなどの独自のインスタンスを作成し、それを使用します。

同期を必要とする場合(トラフィックが発生すると避けてください)、synchornizedまたはReentrantLockはほぼ同じパフォーマンスを提供します。それは再びどのオブジェクトがロックされているかなどを監視する必要があるかどうかに依存します.Webアプリケーションでは、絶対に必要でない限り、推奨されません。

+0

スレッドの閉じ込めを達成する方法の詳細を教えてください。 – missingfaktor

関連する問題