Je veux partager une variable entre plusieurs threads comme ceci:
boolean flag = true;
T1 main = new T1();
T2 help = new T2();
main.start();
help.start();
Je voudrais partager flag
entre le fil principal et le fil d'aide où ce sont deux classes Java que j'ai créées. Est-il possible de le faire? Merci!
Tous les deux T1
et T2
peut faire référence à une classe contenant cette variable.
Vous pouvez alors rendre cette variable volatile, ce qui signifie que
Les modifications apportées à cette variable sont immédiatement visibles dans les deux threads.
Voir cet article pour plus d'informations.
Les variables volatiles partagent les caractéristiques de visibilité des caractéristiques synchronisées mais aucune des caractéristiques d'atomicité. Cela signifie que les threads vont automatiquement voir la valeur la plus récente pour les variables volatiles. Ils peuvent être utilisés pour assurer la sécurité des threads, mais uniquement dans un ensemble de cas très restreint: ceux qui n'imposent pas de contraintes entre plusieurs variables ou entre la valeur actuelle d'une variable et ses valeurs futures.
Et notez les avantages/inconvénients de l'utilisation de volatile
par rapport à des moyens plus complexes de partage d'état.
En plus des autres suggestions - vous pouvez également envelopper l'indicateur dans une classe de contrôle et en faire une dernière instance dans votre classe parent:
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();
}
}
}
Pour le rendre visible entre les instances de T1
et T2
vous pourriez faire en sorte que les deux classes contiennent une référence à un objet qui contient la variable.
Si la variable doit être modifiée lors de l'exécution des threads, vous devez envisager la synchronisation. La meilleure approche dépend de vos besoins exacts, mais les principales options sont les suivantes:
volatile
;AtomicBoolean
;L'utilisation de static
n'aidera pas votre cas.
L'utilisation de synchronize
verrouille une variable lorsqu'elle est utilisée par un autre thread.
Vous devez utiliser le mot clé volatile
pour maintenir la variable à jour parmi tous les threads.
L'utilisation de volatile est une autre façon (comme le wrapper atomique synchronisé) de sécuriser le thread de classe. Thread safe signifie qu'une méthode ou une instance de classe peut être utilisée par plusieurs threads en même temps sans aucun problème.
Vous pouvez utiliser les variables de verrouillage "a" et "b" et les synchroniser pour verrouiller la "section critique" dans l'ordre inverse. Par exemple. Notifier "a" puis Verrouiller "b", "IMPRIMER", Notifier "b" puis Verrouiller "a".
Veuillez vous référer au code ci-dessous: -
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();
}
}
}
}
}
SORTIE: - 1 A 2 B 3 A 4 B 5 A 6 B 7 A 8 B 9 A 10 B