2009-07-16 6 views
-2

Je rencontre des problèmes avec Synchronisé ne se comporte pas la façon dont je pense, je tentai utilisant le mot clé volatile aussi:Java Synchronized et fils

Shared Object:

public class ThreadValue { 

    private String caller; 
    private String value; 

    public ThreadValue(String caller, String value) { 
     this.value = value; 
     this.caller = caller; 
    } 

    public synchronized String getValue() { 
     return this.caller + "  " + this.value; 
    } 
    public synchronized void setValue(String caller, String value) { 
     this.caller = caller; 
     this.value = value; 
    } 
} 

Discussion 1:

class CongoThread implements Runnable { 
    private ThreadValue v; 
    public CongoThread(ThreadValue v) { 
     this.v = v; 
    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      v.setValue("congo", "cool"); 
      v.getValue(); 
     } 
    } 
} 

discussion 2:

class CongoThread implements Runnable { 
    private ThreadValue v; 
    public CongoThread(ThreadValue v) { 
    this.v = v; 

    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      v.setValue("congo", "lame"); 
      v.getValue(); 
     } 
    } 
} 

Appel Classe:

class TwoThreadsTest { 
    public static void main (String args[]) { 

     ThreadValue v = new ThreadValue("", ""); 
     Thread congo = new Thread(new CongoThread(v)); 
     Thread libya = new Thread(new LibyaThread(v)); 

     libya.start(); 
     congo.start(); 
    } 
} 

De temps en temps je reçois "In Libya Thread congo cool" qui ne devrait jamais arriver. Je pense que:
"In Libya Thread libya awesome"
"In Congo Thread congo cool"

Je ne vous attendez qu'ils soient mélangés.

+1

Comment pourriez-vous vous attendre à "En Libye Thread libya awesome"? votre programme ne contient pas le mot "génial" –

Répondre

1

Qu'est-ce qui se passe est le suivant:

  1. Discussion 1 définit la valeur
  2. Discussion 2 définit la valeur
  3. Discussion 1 lit la valeur définie par fil 2.

Pour corriger cela, vous devez avoir 1 objet de verrouillage qui protège les getter/les fonctions set appellent les deux threads. La meilleure façon de procéder est de créer une méthode synchronisée supplémentaire qui fait à la fois l'ensemble et le get. Cependant, parfois, ce n'est pas souhaitable. Dans ce cas, donnez aux deux threads un objet lock. Ce qui est juste un objet simple. Ce qu'ils utilisent ensuite dans un bloc synchronisé.

La mise en œuvre de chaque fil aimerait comme suit, notez qu'ils doivent avoir exactement le même objet!

Object lockObject = new Object(); 
Thread t1 = new CongroThread(v, lockObject); 
Thread t2 = new LibyaThread(v, lockObject); 

... 

class CongoThread implements Runnable { 
    private ThreadValue v; 
    private Object lockObject; 

    public CongoThread(ThreadValue v, Object lockObject) { 
    this.v = v; 
    this.lockObject = lockObject, 
    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      synchronized(lockObject) 
      { 
       v.setValue("congo", "lame"); 
       v.getValue(); 
      } 
     } 
    } 
} 
0

Avez-vous synchronisé les appels System.out.print? Sans synchronisation, ils sont thread safe, mais peuvent ne pas émettre dans le bon ordre.

synchronzied(System.out) { 
    System.out.print(....); 
    System.out.flush(); 
} 
1

Vous êtes seulement la synchronisation de l'accès à getValue et setValue pas séparément les deux-liner

v.setValue("congo", ..); 
v.getValue(); 

Alors bien sûr, les deux fils peut entrelacer entre son setValue et getValue

Questions connexes