このように複数のスレッド間で変数を共有したい:
boolean flag = true;
T1 main = new T1();
T2 help = new T2();
main.start();
help.start();
メインスレッドとヘルプスレッド間でflag
を共有したいのですが、これらは2つの異なるJava私が作成したクラスです。これを行う方法はありますか?ありがとう!
どちらも T1
およびT2
は、この変数を含むクラスを参照できます。
その後、この変数volatileを作成できます。これは、
その変数への変更は、両方のスレッドですぐに表示されます。
詳しくは この記事 をご覧ください。
揮発性変数は同期の可視性機能を共有しますが、原子性機能は共有しません。つまり、スレッドは自動的に揮発性変数の最新の値を参照します。これらはスレッドセーフティを提供するために使用できますが、非常に限られた場合にのみ使用できます。複数の変数間または変数の現在値とその将来値の間に制約を課さない場合のみです。
また、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();
}
}
}
T1
とT2
のインスタンス間で可視化するには、2つのクラスに変数を含むオブジェクトへの参照を含めることができます。
スレッドの実行中に変数を変更する場合は、同期を考慮する必要があります。最適なアプローチは要件に応じて異なりますが、主なオプションは次のとおりです。
volatile
;にします。AtomicBoolean
;に変換します。static
を使用しても問題は解決しません。
synchronize
を使用すると、変数が別のスレッドで使用されているときにロックされます。
volatile
キーワードを使用して、すべてのスレッド間で変数を更新し続ける必要があります。
Volatileを使用することは、クラスをスレッドセーフにする別の方法(同期、アトミックラッパーなど)です。スレッドセーフとは、メソッドまたはクラスインスタンスを問題なく複数のスレッドで同時に使用できることを意味します。
ロック変数「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