2011-06-22 8 views
-1

このコードがスレッドセーフであるか/同期の機能を置き換えるかどうかを確認できますか?複数のスレッドへのアクセスを制限したいのですか?マルチスレッドのためのJavaの "synchronized"キーワードの代わりに

class CheckSynch{ 

    public static booloean check=true; 

    public static void func() // I am trying to write alternative code for synchronized function 
    { 
    if(check) { 
     check=false; 
     //body of function 
     check=true; 
     notifyAll(); 
    } else { 
     wait(); 
    } 
    } 
} 
+4

コード例が混乱しています。 – Rihards

+4

私を信じて、synchronizedキーワードの代わりに書く必要はありません。既にこの井戸を設計しているあなたよりもはるかに賢い人、犯罪はありません。 –

+3

このコードは実行されず、スレッドセーフではありません。 wait/notifyはsynchronizedブロック内になければなりません。そうでなければ、何も待ったり通知したりすることはありません。 – Robin

答えて

7

適切な同期を使用しないものは、すべて破損する可能性があります。 2つのハードウェアスレッドがある場合、それらは同時に実行されるため、checkのチェックと変更の間に、別のスレッドが来て変更する可能性があります。

私はなぜ​​を捨てようとしているのか分かりませんが、同期されていない機能を使って何をしようとしていても、うまくいかず、再生が難しいバグが発生します。

2

いいえ、wait()は同期ブロック内にある必要があります。

0

​​ブロックを静的メソッドで回避することを常にお勧めします。あなたが読み取り/書き込み基準に基づいてスレッドをブロックするために探している場合..あなたは常にあなた自身のロック/ sychronizatonを書くReentrantReadWriteLock

+2

"静的メソッドで同期ブロックを避ける"ことをお勧めします。 –

5

を使用することができますが、私は、EboMikeに同意

は、コンパイルコードを書いて、非常に高度なトピックです高度なトピックではありません。これが本当に良いアイデアならあなた自身に尋ねなければなりません。

あなたは、あなたが同期を所有書きたいWHYしかし、あなたは言っていない

final Lock lock = new ReentrantLock(); 

public static void func() { 
    lock.lock(); 
    try { 
     //body of function 
    } finally { 
     lock.unlock(); 
    } 
} 

ような何かを書くことができます。ロックを取得するのにかかる時間は1〜2マイクロ秒です。

代わりにビジーループを使用できます。

final AtomicBoolean lock = new AtomicBoolean(); 

public static void func() { 
    // wait for the lock to be false and set it to true. 
    while(lock.getAndSet(true)); 
    try { 
     // body of function 
    } finally { 
     lock.set(false); 
    } 
} 
+0

@Peter Lawrey、私はあなたが 'compareAndSet(false、true)'を意味するとは思わない 'getAndSet(true)'。 +1良い選択肢。 –

+0

あなたは 'compareAndSet'も実行できますが、' boolean'は2つの可能な値しか持っていません。私は、あなたが気持ちがはっきりしているものを使用します。 –

+0

@Peter、私はgetAndSetが最初に投稿されたように動作する方法を自分自身に納得させようとしています。値が 'false'の場合、ロックは空いていることを意味します。だから 'while(lock.getAndSet(true))'はじめて失敗するでしょう。しかし、それは洪水門を開くようなものです。 2回目はそれを通し、誰かが出るまで他のすべてのスレッドによって1回おきに試行します。値が反転されているとうまくいくと思います。 –

関連する問題