スレッド化のためのこれら 2 つのコードの違いがわかりません。相互排除のためだと思いますが、何が違いなのか理解できません。
public synchronized void Method1 () {
}
public myFunction (){
synchronized (this) {
}
}
助けてくれてありがとう。
スレッド化のためのこれら 2 つのコードの違いがわかりません。相互排除のためだと思いますが、何が違いなのか理解できません。
public synchronized void Method1 () {
}
public myFunction (){
synchronized (this) {
}
}
助けてくれてありがとう。
唯一の違いは、パフォーマンスを大幅に向上させることができるロックによって保護される操作の数を減らすことです。
例: 入力時に大きな数の因数の配列を与えるサーブレットがあり、サーブレットが起動される頻度をカウントしたいとします。問題は、状態変数へのアクセスを同期することですrequestsCount
//Poor performance
class PoorFactorizer implements Servlet {
private int requestsCount = 0;
public synchronized void service(ServletRequest req, ServletResponse res) {
BigInteger numberToFactorize = extractFromRequest(req);
BigInteger[] factors = factorize(numberToFactorize); // long lasting
// operation makes everyone wait
requestCount++;
encodeResponse(res, factors);
}
}
//Better perfomance
class PoorFactorizer implements Servlet {
private int requestsCount = 0;
public void service(ServletRequest req, ServletResponse res) {
BigInteger numberToFactorize = extractFromRequest(req);
BigInteger[] factors = factorize(numberToFactorize);
// since we need to guard only the class' state
// let's guard only the operation with the state
synchronized(this) {
requestCount++;
}
encodeResponse(res, factors);
}
}
UPD:傑作「Java Concurrency in Practice」(第 2 章) で非常に優れた説明を読むことができます。この本を最初から最後まで読むことを強くお勧めします。
違いを見ます
メソッドを同期すると、メソッドはこのオブジェクトによって暗黙的にロックされ、すべてがロックするのに重要ではない場合でも、メソッド全体がロックされます。(パフォーマンスの低下)。
ブロックを同期すると、ロック (パフォーマンスの向上) の重要なコードが選択され、ロック オブジェクトを選択できます。[空席を予約するなど、重要なアクションを実行するオブジェクトが複数あり、複数の予約リクエストがあるとします。全員が同時に予約することを許可したり、これ (現在のオブジェクト) をロックしたくない場合があります。このシナリオでは、ロックを取得して操作を実行するための共通オブジェクトが必要です。一度に、ロックは任意の 1 つのオブジェクトによって取得できます。したがって、一度に 1 つのリクエスタ ブック チケットのみを保証します。したがって、重複予約は許可されません]。
違いは、相互排除の粒度です。上記のコードでは、一度に 1 つのスレッドだけが Method1 を呼び出すことができます。複数のスレッドが myFunction を呼び出す可能性があります。ただし、myFunction は「this」で同期されたブロックに入る以外は何もしないため、実質的な違いはありません。ただし、myFunction には、複数のスレッドによって同時に実行される可能性のある同期ガードの外部にある他のコードが含まれる可能性があります。
ロックの観点からは、どちらも同じように動作します。唯一の違いは、同期ブロックに使用される null 以外のオブジェクトが存在する可能性があることです。
public myFunction (){
synchronized (anyObject) {
}
}
これで、このオブジェクトに基づいてこのブロックを同期できます。
synchronized キーワードが使用された場合については、その同期スコープは呼び出し元のオブジェクトに依存します。
これがお役に立てば幸いです。コーディングをお楽しみください!!!
方法があれば
public synchronized void methodA()
{
while(condition)
{
// do Something That Takes A Minute ;
}
// do Something That Needs A Lock;
while(condition)
{
// do Something That Takes Another Minute ;
}
}
2 分以上ロックを保持します。
public void methodA()
{
while(condition)
{
// do Something That Takes A Minute ;
}
synchronized(this)
{
// do Something That Needs A Lock;
}
while(condition)
{
// do Something That Takes Another Minute ;
}
}
並行性の高いアプリケーションの場合、ロックが保持される時間の違いは非常に重要です。
おそらく、メソッド 2 を 2 つのメソッドに分割し、メソッド レベルで同期化を適用できますが、それは場合によっては不適切なコードにつながる可能性があります。
SO 両方の機能は Java によって提供されます。