複数の異なるスレッド間で変数を共有する:私はこのような複数のスレッド間で変数を共有したい
boolean flag = true;
T1 main = new T1();
T2 help = new T2();
main.start();
help.start();
私はこれらは私が「二つの異なるJavaクラスがあり、メインとヘルプスレッド間flag
を共有したいです作成されました。これを行う方法はありますか?ありがとう!
複数の異なるスレッド間で変数を共有する:私はこのような複数のスレッド間で変数を共有したい
boolean flag = true;
T1 main = new T1();
T2 help = new T2();
main.start();
help.start();
私はこれらは私が「二つの異なるJavaクラスがあり、メインとヘルプスレッド間flag
を共有したいです作成されました。これを行う方法はありますか?ありがとう!
T1
とT2
の両方は、この変数を含むクラスを参照できます。この変数をとし、変数にすることができます。これは、その変数への変更が両方のスレッドで即座に見えることを意味します。
詳細については、this articleを参照してください。
揮発性変数は、視認性の同期の機能が、アトミック機能の どれを共有しています。つまり、スレッドは に自動的に揮発性変数の最新の値を表示します。 これらは、スレッドの安全性を提供するために使用できますが、 複数の変数の間、または変数の現在の値と の将来の値の間に制約を課すものではありません。
揮発性とより複雑な状態を共有する手段を使用することの長所/短所に注意してください。
がT1
のインスタンスとの間で、それを目に見えるようにすることになっていT2
あなたは2つのクラスが変数を含むオブジェクトへの参照が含まれて作ることができます。
スレッドが実行されているときに変数を変更する場合は、同期を考慮する必要があります。最適なアプローチは、正確な要件によって異なりますが、主なオプションは以下のとおりです。
volatile
;AtomicBoolean
に変換します。- あなたはまた、コントロールクラスにフラグをラップすることができますし、あなたの親クラスでの最後のインスタンスを作る:
public class Test {
class Control {
public volatile boolean flag = false;
}
final Control control = new Control();
class T1 implements Runnable {
@Override
public void run() {
while (!control.flag) {
}
}
}
class T2 implements Runnable {
@Override
public void run() {
while (!control.flag) {
}
}
}
private void test() {
T1 main = new T1();
T2 help = new T2();
new Thread(main).start();
new Thread(help).start();
}
public static void main(String[] args) throws InterruptedException {
try {
Test test = new Test();
test.test();
} catch (Exception e) {
e.printStackTrace();
}
}
}
ありがとうございます。 OldCurmufgeon、それは私が探していたものです;) – user1031431
あなたはロック変数を使用することができます「」 「b」を同期させ、「クリティカルセクション」を逆の順序でロックする。例えば。 "a"を通知してから "b"をロックし、 "PRINT"、 "b"を通知して "a"をロックします。
コード下記参照してください: -
public class EvenOdd {
static int a = 0;
public static void main(String[] args) {
EvenOdd eo = new EvenOdd();
A aobj = eo.new A();
B bobj = eo.new B();
aobj.a = Lock.lock1;
aobj.b = Lock.lock2;
bobj.a = Lock.lock2;
bobj.b = Lock.lock1;
Thread t1 = new Thread(aobj);
Thread t2 = new Thread(bobj);
t1.start();
t2.start();
}
static class Lock {
final static Object lock1 = new Object();
final static Object lock2 = new Object();
}
class A implements Runnable {
Object a;
Object b;
public void run() {
while (EvenOdd.a < 10) {
try {
System.out.println(++EvenOdd.a + " A ");
synchronized (a) {
a.notify();
}
synchronized (b) {
b.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B implements Runnable {
Object a;
Object b;
public void run() {
while (EvenOdd.a < 10) {
try {
synchronized (b) {
b.wait();
System.out.println(++EvenOdd.a + " B ");
}
synchronized (a) {
a.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
OUTPUT: - 1 2 B 3 4 B 5 6 B 7 8 B 9 A 10 B
ありがとうございますが、たとえばT1の内部から「フラグ」を参照してください。私はParentClass.flagのようなものを試しましたが(ParentClassは "main"と "help"を開始するクラスです)、それは動作していないようです... – user1031431
T1/T2を含むクラスへの参照をインスタンス化します、フラグをそのクラスのメンバーにしますか? –