2016-06-11 20 views
-1

ich nicht in der Lage bin zu synchronisierenden Blöcke in Javasynchronisierten Block funktioniert nicht ganz richtig

ich diesen folgenden Beitrag lesen zu bekommen, aber habe ganz über syn-Blöcke und Schlösser nicht bekommen

Synchronized block not working

i nicht wissen, unter Code, warum nicht gleichförmige Anordnung von a, B, C-Schema ausgibt auch nachdem ich es synchronisiert ..

public class synchronizeblock 
{ 
    static StringBuffer s=new StringBuffer(); 
    public static void main(String []args) 
    { 
     Threading t1=new Threading(s,'a'); 
     Threading t2=new Threading(s,'b'); 
     Threading t3=new Threading(s,'c'); 
     t1.start(); 
     t2.start(); 
     t3.start();  
    } 
} 
class Threading extends Thread 
{ 
    StringBuffer sb; 
    char ch; 

    Threading() 
    { 

    } 
    Threading(StringBuffer sb,char ch) 
    { 
     this.sb=sb; 
     this.ch=ch; 
    } 
    public void run() 
    { 
     synchronized(this) // this(current instance) acts as lock ?? 
     { 
       for(int i=0;i<20;++i) 
       { 
        System.out.print(ch); 
       } 
     }  
    } 

} 

eine von c Ases des Ausgangs ist wie folgt:

bbbbbbbbbbbbbaccccccccccccccccccccaaaaaaaaaaaaaaaaaaabbbbbbb

meine Sorge ist, dass, sobald ein Thread gestartet wird, sagt Faden mit Charakter ‚b‘ (sei es „ein“ thread-) sollte es nicht abgeschlossen sein, bevor ein anderer Thread Chance zu laufen wird, weil Thread „eins“ auf dem Objektsperre bekam, korrigieren sie mich falsch, wenn Uhr und ich habe folgende Fragen

  1. es wirklich verwirrend „was wird gesperrt“ und „w Hut wirkt als Schloss ". So erklären, was genau in meinem Code gesperrt wurde

  2. und was soll ich tun einheitliche Ausgabe zu erhalten (mit den Worten einheitliche Ausgabe hier, ich meine, dass, sobald ein Thread seinen Charakter beginnt sollte 20-mal gedruckt werden)

+1

'synchronized' nimmt eine Sperre für das gegebene Objekt,' this' ist der Fall. Sie haben 3 verschiedene 'Threading'-Instanzen, also sperren sie 3 verschiedene Objekte, und da nichts anderes versucht, diese Objekte zu sperren, haben die Sperren keine Wirkung. – Andreas

+0

Wenn Sie sagen, "habe das Objekt verriegelt", welches Objekt meinst du? –

+0

@Andreas so betrachten synchronisiert (aaaa) so aaaa nicht als Sperre, sondern es wird gesperrt, korrigieren Sie mich, wenn ich falsch bin .... – viru

Antwort

2

allererst sind StringBuffer

String-Puffer für die Verwendung durch mehrere Threads sicher sind. Die Methoden werden bei Bedarf synchronisiert, so dass sich alle Operationen in einer bestimmten Instanz so verhalten, als ob sie in einer seriellen Reihenfolge auftreten, die mit der Reihenfolge der Methodenaufrufe von jedem der beteiligten einzelnen Threads übereinstimmt.

und der Rest Sie meine Ausgabe in Unterseite Ihrer Frage, aber Problem über nicht gedruckt wie diese A's B's C's lesen kann sein, dass Ihre Thread s laufen, auch wenn der aktuelle Thread nicht für das beenden join() Methode seiner Tells verwenden der andere Thread warten, bis meine Aufgabe sein Ende den Auftrag so gehen sie dazu Ihre main Methoden so aussehen

 Threading t1 = new Threading(s,'a'); 
     Threading t2 = new Threading(s,'b'); 
     Threading t3 = new Threading(s,'c'); 
     t1.start(); 
     t1.join(); 
     t2.start(); 
     t2.join(); 
     t3.start(); 
0

Verwenden Sie die sb für die Synchronisierung, weil Sie sonst nicht mit den anderen Threads synchronisieren (Sie sperren das Objekt für sich). Oder erstellen Sie ein Sperrobjekt, das zum Synchronisieren zwischen den drei verschiedenen Objekten verwendet wird.

public class Threading extends Thread 
{ 
    private Object synchronizationContext; 
    private StringBuffer sb; 
    private char ch; 

    Threading(StringBuffer sb,char ch, Object synchronizationContext) 
    { 
     this.sb=sb; 
     this.ch=ch; 
    } 
    public void run() 
    { 
     synchronized(synchronizationContext) 
     { 
      for(int i=0;i<20;++i) 
      { 
       System.out.print(ch); 
      } 
     }  
    } 
} 

und main verwenden die gleiche synchronizationContext für alle.

public static void main(String []args) 
{ 
    Object synchronizationContext = new Object(); 
    Threading t1 = new Threading(s,'a', synchronizationContext); 
    Threading t2 = new Threading(s,'b', synchronizationContext); 
    Threading t3 = new Threading(s,'c', synchronizationContext); 
    t1.start(); 
    t2.start(); 
    t3.start();  
} 
0
  1. es ist wirklich conf mit „was wird gesperrt“ und „was wirkt als Sperre“

Nicht sicher, was Sie fordern. Wenn wir eine synchronized (obj) machen, dann ist die obj, was gesperrt ist. Die Threads machen das Sperren, das blockieren kann, wenn ein anderes Thread bereits das Schloss enthält. Es ist nicht korrekt zu sagen, dass die obj "als eine Sperre fungiert".

synchronized(this) // this(current instance) acts as lock ?? 

Sie sind Sperren auf this, die das Problem ist, siehe unten.

2.und was soll ich einheitliche Ausgabe zu erhalten tun, um (mit den Worten einheitliche Ausgabe hier

In Ihrem Fall das Problem ist, dass Sie eine Synchronisations auf this. Jeder Thread auf einem blockiert . verschiedene Objekt Wenn Sie ihnen eine Mutex-Sperre haben exklusiven Zugriff auf Druck ihre Charaktere haben wollen, dann müssen Sie in einem gemeinsamen Objekt zu übergeben, dass sie alle sperren auf:

final Object lock = new Object(); 
Threading t1 = new Threading(lock,'a'); 
Threading t2 = new Threading(lock, b'); 
Threading t3 = new Threading(lock,'c'); 
... 
class Threading extends Thread { 
    final Object lock; 
    final char ch; 
    public Threading(Object lock, char ch) { 
     this.lock = lock; 
     this.ch = ch; 
    } 
    public void run() { 
     // lock on a common lock object in all 3 threads 
     synchronized (lock) { 
      for(int i = 0; i < 20; i++) { 
       System.out.print(ch); 
      } 
     } 
    } 
}