I want to share a variable between multiple threads like this:
boolean flag = true;
T1 main = new T1();
T2 help = new T2();
main.start();
help.start();
I'd like to share flag
between main and help thread where these are two different Java classes I've created. Is any way to do this? Thanks!
Both T1
and T2
can refer to a class containing this variable.
You can then make this variable volatile, and this means that
Changes to that variable are immediately visible in both threads.
See this article for more info.
Volatile variables share the visibility features of synchronized but none of the atomicity features. This means that threads will automatically see the most up-to-date value for volatile variables. They can be used to provide thread safety, but only in a very restricted set of cases: those that do not impose constraints between multiple variables or between a variable's current value and its future values.
And note the pros/cons of using volatile
vs more complex means of sharing state.
In addition to the other suggestions - you can also wrap the flag in a control class and make a final instance of it in your parent class:
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();
}
}
}
- Making it static could fix this issue.
- Reference to the main thread in other thread and making that variable visible
To make it visible between the instances of T1
and T2
you could make the two classes contain a reference to an object that contains the variable.
If the variable is to be modified when the threads are running, you need to consider synchronization. The best approach depends on your exact requirements, but the main options are as follows:
- make the variable
volatile
; - turn it into an
AtomicBoolean
; - use full-blown synchronization around code that uses it.
Using static
will not help your case.
Using synchronize
locks a variable when it is in use by another thread.
You should use volatile
keyword to keep the variable updated among all threads.
Using volatile is yet another way (like synchronized, atomic wrapper) of making class thread safe. Thread safe means that a method or class instance can be used by multiple threads at the same time without any problem.
You can use lock variables "a" and "b" and synchronize them for locking the "critical section" in reverse order. Eg. Notify "a" then Lock "b" ,"PRINT", Notify "b" then Lock "a".
Please refer the below the code :-
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 A 2 B 3 A 4 B 5 A 6 B 7 A 8 B 9 A 10 B
来源:https://stackoverflow.com/questions/13582395/sharing-a-variable-between-multiple-different-threads