次のように、複数のスレッド間で変数を共有したいと思います。
boolean flag = true;
T1 main = new T1();
T2 help = new T2();
main.start();
help.start();
メインスレッドとヘルプスレッドの間で共有したいと思いflag
ます。これらは、私が作成した2つの異なるJavaクラスです。これを行う方法はありますか?ありがとう!
次のように、複数のスレッド間で変数を共有したいと思います。
boolean flag = true;
T1 main = new T1();
T2 help = new T2();
main.start();
help.start();
メインスレッドとヘルプスレッドの間で共有したいと思いflag
ます。これらは、私が作成した2つの異なるJavaクラスです。これを行う方法はありますか?ありがとう!
とは両方ともT1
、T2
この変数を含むクラスを参照できます。
次に、この変数を揮発性にすることができます。これは、その変数への変更が両方のスレッドですぐに表示されることを意味します。
詳細については、この記事を参照してください。
揮発性変数は、同期された可視性機能を共有しますが、原子性機能は共有しません。これは、スレッドが揮発性変数の最新の値を自動的に確認することを意味します。これらはスレッドセーフを提供するために使用できますが、非常に制限された一連のケースでのみ使用できます。複数の変数間、または変数の現在の値と将来の値の間に制約を課さない場合です。
volatile
また、状態を共有するためのより複雑な手段と使用の長所/短所に注意してください。
他の提案に加えて、フラグをコントロールクラスでラップし、親クラスでその最終インスタンスを作成することもできます。
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();
}
}
}
使用しても問題は解決しstatic
ません。
変数を使用synchronize
すると、別のスレッドで使用されているときに変数がロックされます。
volatile
すべてのスレッド間で変数を最新の状態に保つには、keywordを使用する必要があります。
volatileの使用は、クラススレッドを安全にするもう1つの方法(同期されたアトミックラッパーなど)です。スレッドセーフとは、メソッドまたはクラスインスタンスを複数のスレッドで同時に問題なく使用できることを意味します。
のインスタンス間で表示T1
できるT2
ようにするには、2つのクラスに変数を含むオブジェクトへの参照を含めることができます。
スレッドの実行中に変数を変更する場合は、同期を考慮する必要があります。最善のアプローチは正確な要件によって異なりますが、主なオプションは次のとおりです。
volatile
;AtomicBoolean
;に変えてくださいロック変数「a」と「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();
}
}
}
}
}
出力:
1 A
2 B
3 A
4 B
5 A
6 B
7 A
8 B
9 A
10 B