私には2つの方法があります:a()とb()。複数のスレッドが同時に任意のメソッドにアクセスすることは問題ありませんが(これは望ましいことです)、実行a()中にスレッドを入力したくありませんb()。それ、どうやったら出来るの?
編集1
4つのスレッドがあり、Thread 1にアクセスしているとしましょうA()。私が欲しいのは、4つのスレッドすべてが使用すべきではないということB()です。
私には2つの方法があります:a()とb()。複数のスレッドが同時に任意のメソッドにアクセスすることは問題ありませんが(これは望ましいことです)、実行a()中にスレッドを入力したくありませんb()。それ、どうやったら出来るの?
4つのスレッドがあり、Thread 1にアクセスしているとしましょうA()。私が欲しいのは、4つのスレッドすべてが使用すべきではないということB()です。
下部にある更新を確認してください-このアプローチは機能しないと思います。情報のためにそれを残します。
セマフォを使用できます:
b()実行しようとしているスレッドは、a()の実行が終了するまでブロックさb()れます。b()ていて、2番目のスレッドが実行しようとすると、次のb()ことが可能になります。a()実行されていないときに2つのスレッドが実行b()されると、両方が実行されます注:スレッドが入っa()て「セマフォテスト」に合格すると、別のスレッドが終了するb()前に実行を開始できます。a()
原則は機能するはずですが、私はそれをテストしていません。
private final Semaphore inB = new Semaphore(1);
public void a() throws InterruptedException {
inB.acquire(); //blocks until no thread is in b any longer
//now we are good to go and execute a()
//release the semaphore immediately for other threads who want to run a()
inB.release();
//rest of your code here
}
public void b() {
//does not block to allow 2 thread running b() simultaneously
boolean needToRelease = inB.tryAcquire();
//rest of your code
//if the permit was acquired, release it to allow threads to run a()
if (needToRelease) {
inB.release();
}
}
編集
あなたの意図は明確ではなく、あなたのコメントの1つが相互に排他的でありたいa()と言っているので、あなたの質問は編集されました(多くのスレッドはどちらかまたは並列に実行できますが、並列に実行してはいけません)。その場合、2つのセマフォとで同じロジックを使用できます。b()a()b()a()b()inAinB
更新=>バグ
別の回答へのコメントで@yshavitが指摘しているように、次のシナリオのコードには競合状態があります。
a()され、取得されますinBb()され、取得に失敗しますinBinBa()され、なんとか取得できますinBb()これはSempahoresだけでは達成できないようです。この答えはより良い解決策を与えます。
簡単にするために例外処理は省略されています。
public class Test {
private final Object lock = new Object();
private int counterA;
private int counterB;
public void a() {
synchronized(lock) {
while(counterB > 0) {
lock.wait();
}
++counterA;
}
// do work
synchronized(lock) {
--counterA;
lock.notifyAll();
}
}
public void b() {
synchronized(lock) {
while(counterA > 0) {
lock.wait();
}
++counterB;
}
// do work
synchronized(lock) {
--counterB;
lock.notifyAll();
}
}
}
java.util.concurrent.locksは、いくつかのロックを含むJavaパッケージです。
でb()、同じロックで同じことを行います
非対称の動作を処理したい場合は、ReadWriteLockを使用できます。a ()はリーダーで、b()はライターです。いくつかのb()はロックしますが、いくつかのa()はロックしません。