2017-03-20 2 views
-1

Dies ist meine Beispielklasse: Ich habe ein gemeinsames Objekt CustomerAccount zwischen zwei Threads Man und Woman geteilt. Wenn ich das Programm starte, sind die Ergebnisse konsistent. Wieso ist es so?Wann müssen wir eigentlich synchronisieren? Meine Themen sind natürlich synchronisiert

Hauptklasse:

package testjava; 

public class PlaywithThreads { 

    public static void main(String[] args) throws InterruptedException { 
     // TODO Auto-generated method stub 
     CustomerAccount ca=new CustomerAccount(0); 
     ThreadRunner1 tr1=new ThreadRunner1(ca,"Man"); 
     ThreadRunner1 tr2=new ThreadRunner1(ca,"Woman"); 

     tr1.start(); 
     tr2.start(); 
     tr1.join(); 
     tr2.join(); 
     System.out.println("Final amount left after month"+ca.acctBalance); 
    } 
} 

Thread-Klasse:

package testjava; 

public class ThreadRunner1 extends Thread{ 
    private CustomerAccount ca; 

    ThreadRunner1 (CustomerAccount ca,String name) 
     { 

      super (name); 

      this.ca = ca; 
      System.out.println("after this it will create new object"); 
     } 

@Override 
public void run() { 
    Thread current = Thread.currentThread(); 
    String name = current.getName(); 
    System.out.println("Name is"+name); 

    // TODO Auto-generated method stub 
    if (name.equals("Man")){ 
     //CustomerAccount caMan = new CustomerAccount(); 
     /*ca.creditSalary(80000); 
     System.out.println(name+""+ca.acctBalance); 
     ca.debitFood(8000); 

     ca.debitLoans(40000); 
     System.out.println(name+""+ca.acctBalance); 
     ca.creditBonus(3); 

     ca.debitTransport(2000);*/ 
     ca.acctBalance=ca.acctBalance+80000; 
     ca.acctBalance=ca.acctBalance-8000; 
     ca.acctBalance=ca.acctBalance-40000; 
     ca.acctBalance=ca.acctBalance+3; 
     ca.acctBalance=ca.acctBalance-2000; 
     System.out.println(name+"----------finally------------"+ca.acctBalance); 
    } 

    if (name.equals("Woman")){ 

     //CustomerAccount caWoMan = new CustomerAccount(); 
     /*ca.creditSalary(50000); 
     System.out.println(name+""+ca.acctBalance); 
     ca.creditBonus(4); 

     ca.debitClothes(20000); 


     ca.debitLoans(9000);*/ 
     ca.acctBalance=ca.acctBalance+50000; 
     ca.acctBalance=ca.acctBalance+4; 
     ca.acctBalance=ca.acctBalance-20000; 
     ca.acctBalance=ca.acctBalance-9000; 
     System.out.println(name+"---------Finally-------"+ca.acctBalance); 
    } 

} 
} 

Shared Object:

package testjava; 

public class CustomerAccount { 

    int acctBalance; 


    // private static int counter; 

    public CustomerAccount(int initialBalance) { 
     System.out.println("entered"); 

     this.acctBalance=initialBalance; 
     //System.out.println("objects created******************"+counter); 
    } 
    public void debitFood(int amt){ 
     System.out.println("debiting food items::for"+Thread.currentThread().getName()); 
     acctBalance = acctBalance-amt; 
     System.out.println("New acct Balance after food debits::"+acctBalance); 
    } 
    public void debitClothes(int amt){ 
     System.out.println("debiting clothescost::"+Thread.currentThread().getName()); 
     acctBalance = acctBalance-amt; 
     System.out.println("New acct Balance after clotehs debits::"+acctBalance); 
    } 
    public void debitTransport(int amt){ 
     System.out.println("debiting transport::"+Thread.currentThread().getName()); 
     acctBalance = acctBalance-amt; 
     System.out.println("New acct Balance after transport debit::"+acctBalance); 
    } 
    public void debitLoans(int amt){ 
     System.out.println("debiting loans::"+Thread.currentThread().getName()); 
     acctBalance =acctBalance-amt; 
     System.out.println("New acct Balance after Loans debit::"+acctBalance); 
    } 
    public void creditSalary(int salary){ 
     System.out.println("crediting salary for ::"+Thread.currentThread().getName()); 
     acctBalance =acctBalance+salary; 
     System.out.println("New acct Balance after salary credit::"+acctBalance); 
    } 
    public void creditBonus(int salary){ 
     System.out.println("crediting bonus for ::"+Thread.currentThread().getName()); 
     acctBalance =acctBalance+salary; 
     System.out.println("New acct Balance after salary credit::"+acctBalance); 
    } 
} 
+0

Ja, weil es das Ergebnis korrekt gibt, nachdem beide Threads ihre Arbeit gemacht haben.51007 das wäre das gleiche Ergebnis, wenn ich die Beträge von einem gemeinsamen Kontostand addiere oder subtrahiere. – WileyCoyote

+0

Was meinen Sie mit "Meine Threads sind natürlich synchronisiert"? Von dem, was ich von unserem Code sehe, sind sie nicht. –

+0

Der Code ist zu einfach, wenn Sie den Effekt der Synchronisation sehen möchten, versuchen Sie, eine zufällige Wartezeit in 'run' Methode hinzuzufügen, etwas wie: ' Thread.sleep (Math.ceil (Math.random() * 1000)) – rascio

Antwort

0

Da die CustomerAccount Objekt geteilt wird Sie die Synchronisierung dort behandeln soll. Dies kann nicht mit direktem Elementzugriff erfolgen (was aus dem Kapselungspunkt ohnehin eine schlechte Idee ist). Ich würde empfehlen, einen Blick in AtomicInteger als ein besserer Typ für acctBalance zu werfen, die Thread-Safe out of the Box ist, aber Sie können auch alle Methoden von CustomerAccount synchronisiert machen.

Es kann aussehen wie die Threads synchronisiert werden, da Sie viel Zugriff auf die Synchronisierung haben System.out.println()! Wenn Sie dieses printf-Debugging entfernen und eine höhere Auslastung erstellen würden, würden Sie ein anderes Verhalten sehen.

+0

Ich habe die println-Anweisungen entfernt, ich verstehe jetzt, dass meine Operationen seriell fortgeführt werden, unabhängig von der Schlafzeit und dem gleichen Ergebnis. Ich denke daran, komplexere Operationen zu erstellen, damit es scheitert. Vorschläge? – WileyCoyote

Verwandte Themen