2012-11-27 10 views

Antwort

17

Sowohl T1 als auch T2 können auf eine Klasse verweisen, die diese Variable enthält. Sie können dann diese Variable volatile machen, und das bedeutet, dass Änderungen an dieser Variablen sofort in beiden Threads sichtbar sind.

Weitere Informationen finden Sie unter this article.

Flüchtige Variablen teilen die Sichtbarkeitseigenschaften von synchronisierten, aber keiner der Atomity-Features. Dies bedeutet, dass die Threads automatisch den aktuellsten Wert für flüchtige Variablen sehen. Sie können verwendet werden, um Thread-Sicherheit, aber nur in einer eingeschränkten Menge von Fällen: diejenigen, die keine Beschränkungen zwischen mehrere Variablen oder zwischen einem aktuellen Wert einer Variablen und zukünftige Werte auferlegen.

und beachten Sie die Vor-/Nachteile der Verwendung von volatilen vs komplexeren Möglichkeiten der Freigabe von Staat.

+0

Vielen Dank für die Antwort, aber wie würdest du? beziehen Sie sich beispielsweise auf "Flagge" von innen T1? Ich habe etwas wie ParentClass.flag versucht (wo ParentClass die Klasse ist, von der ich "main" und "help" starte) und es scheint nicht zu funktionieren ... – user1031431

+0

Instanziiere T1/T2 mit einem Verweis auf ihre enthaltende Klasse , und mache die Flagge ein Mitglied dieser Klasse? –

4
  1. Wenn Sie statisch machen, könnte dieses Problem behoben werden.
  2. Verweis auf den Haupt-Thread in anderen Thread und machen diese Variable sichtbar
3

Um es zwischen den Instanzen von T1 und T2 Sie könnten machen die beiden Klassen enthalten einen Verweis auf ein Objekt sichtbar zu machen, der die Variable enthält.

Wenn die Variable geändert werden soll, während die Threads ausgeführt werden, müssen Sie die Synchronisierung in Betracht ziehen. Der beste Ansatz ist abhängig von Ihren genauen Anforderungen, aber die wichtigsten Optionen sind wie folgt:

  • machen die Variable volatile;
  • drehen Sie es in eine AtomicBoolean;
  • verwenden Sie ausgewachsene Synchronisation um Code, der es verwendet.
6

Zusätzlich zu den anderen Vorschlägen - Sie können auch die Flagge in einem Steuerklasse wickeln und eine endgültige Instanz davon in der übergeordneten Klasse machen:

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(); 
    } 
    } 
} 
+0

Danke euch allen. OldCurmufgeon, das ist was ich gesucht habe;) – user1031431

0

Sie Lock-Variablen verwenden „a“ und "b" und synchronisieren sie zum Sperren des "kritischen Abschnitts" in umgekehrter Reihenfolge. Z.B. Benachrichtige "a", dann "b", "DRUCKEN", Benachrichtige "b" und dann "a".

Siehe die unter dem 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

Verwandte Themen