CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: synchronized

  1. #1
    Join Date
    Aug 2005
    Posts
    98

    synchronized

    I wrote a code about synchronized in JAVA , according to the example of this book



    3.1 A Banking Example
    As an application designer for a major bank, we are assigned to the development team for the
    automated teller machine (ATM). As our first assignment, we are given the task of designing and
    implementing the routine that allows a user to withdraw cash from the ATM. A first and simple
    attempt at an algorithm may be as follows (see Figure 3.1 for the flow chart):
    1. Check to make sure that the user has enough cash in the bank account to allow the withdrawal
    to occur. If the user does not, then go to step 4.
    2. Subtract the amount withdrawn from the user's account.
    3. Dispense the cash from the teller machine to the user.
    4. Print a receipt for the user.


    Given this very simple algorithm, an implementation may be as follows:
    public class
    AutomatedTellerMachine extends Teller {
    public void withdraw(float amount) {
    Account a = getAccount();
    if (a.deduct(amount))
    dispense(amount);
    printReceipt();
    }
    }
    public class Account {
    private float total;
    public boolean deduct(float t) {
    if (t <= total) {
    total -= t;
    return true;
    }
    return false;
    }
    }

    As it turns out, it is possible for two people to have access to the same account (e.g., a joint account).
    One day, a husband and wife both decide to empty the same account, and purely by chance, they
    empty the account at the same time. We now have a race condition: if the two users withdraw from the
    bank at the same time, causing the methods to be called at the same time, it is possible for the two
    ATMs to confirm that the account has enough cash and dispense it to both parties. In effect, the two
    users are causing two threads to access the account database at the same time.

    There is a race condition because the action of checking the account and changing the account status
    is not atomic. Here we have the husband thread and the wife thread competing for the account:
    1. The husband thread begins to execute the deduct() method.
    2. The husband thread confirms that the amount to deduct is less than or equal to the total in the
    account.
    3. The wife thread begins to execute the deduct() method.
    4. The wife thread confirms that the amount to deduct is less than or equal to the total in the
    account.
    5. The wife thread performs the subtraction statement to deduct the amount, returns true, and
    the ATM dispenses her cash.
    6. The husband thread performs the subtraction statement to deduct the amount, returns true,
    and the ATM dispenses his cash.

    The Java specification provides certain mechanisms that deal specifically with this problem. The Java
    language provides the synchronized keyword; in comparison with other threading systems, this
    keyword allows the programmer access to a resource that is very similar to a mutex lock. For our
    purposes, it simply prevents two or more threads from calling our deduct() method at the same time:
    public class Account {
    private float total;
    public synchronized boolean deduct(float t) {
    if (t <= total) {
    total -= t;
    return true;
    }
    return false;
    }
    }
    By declaring the method as synchronized, if two users decide to withdraw cash from the ATM at the
    same time, the first user executes the deduct() method while the second user waits until the first user
    completes the deduct() method. Since only one user may execute the deduct() method at a time, the
    race condition is eliminated.

    Code:
     
    public class deduct {
        
       
        /** Creates a new instance of deduct */
         public  void  deductaccount (int amount)
        {
             
             if (account.total >= amount)
            {
                account.total -= amount;}
    
                if (account.total<0){
                System.out.println("ERROR");
                System.exit(0);
            }
        
             
    }
    }

    Code:
     public class account implements Runnable 
    {
         public static int total=100;
        deduct a = new deduct();  
           public void run()
                {
               a.deductaccount(100); 
                    
                }
        
       
    }
    Code:
      public class Main
    {
        public static void main(String[] args)
        {
          account account = new account();  
           
                     
            Thread thread1 = new Thread(account);
            Thread thread2 = new Thread(account);
    
            thread1.start();
            thread2.start();
        }
    }
    I am leaning thread in JAVA

    The result of this program in to know difference between synchronized
    method and unsynchronized mrthod

    At this case ,Because I don't use synchronized
    it must not print out error.

    because threads run at same time.

    But it prints : ERROR

    why?

    Another question is:

    When I trace this program line by line ,

    after lines , it goes to this line :

    Code:
       
    
    Thread thread1 = new Thread(account);
            Thread thread2 = new Thread(account);
    
            thread1.start();
            thread2.start();
        }
    I think that this program must work line this ( If i am wrong please make me correct):

    1-
    Code:
      # thread1.start();  
    #         thread2.start();
    Thread1 starts, after that , this code will be run :

    Code:
       
    
    # public void run()  
    #             {  
    #            a.deductaccount(100);   
    #                   
    #             }

    After that ,Because of this line :a.deductaccount(100); this code will run:

    Code:
      public class deduct {
        
       
        /** Creates a new instance of deduct */
         public  void  deductaccount (int amount)
        {
             
             if (account.total >= amount)
            {
                account.total -= amount;}
    
                if (account.total<0){
                System.out.println("ERROR");
                System.exit(0);
            }
        
             
    }
    }
    Ok, Now total become 0,

    1- at the same time thread2 has started, and value of total become -100.Then the program must print ERROR

    If I don't understand or can'nt trace, Please guide me









    2- Another question:

    I want to know why after it arrives this line:

    thread1.start();

    Why it doesn't go to deduct class and it goes to this line :

    thread2.start();

    Thanks in advance
    Last edited by Abalfazl; January 1st, 2010 at 12:37 PM.

  2. #2
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: synchronized

    Another question:

    I want to know why after it arrives this line:

    thread1.start();

    Why it doesn't go to deduct class and it goes to this line :

    thread2.start();
    Your main program thread calls the start() method on another thread (thread1) but this doesn't mean that thread 1 will start executing immediately, it may do but it may not. So if you run this program 1000's of times you'll find that sometimes thread1 runs before thread2 is started and sometimes it doesn't.

    When dealing with multiple threads there are no guarantees as to when a particular thread will execute and how much code it will execute during it's turn. If you need to control execution order you need to use the classes in the java.util.concurrent package. Remember, what happens (the execution order) on your machine won't necessarily be the same each time you run the program and it won't be the same as on a different computer.

  3. #3
    Join Date
    Aug 2005
    Posts
    98

    Re: synchronized

    Thanks!

    But may you answer the first question?

  4. #4
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: synchronized

    My post did answer the first question. You can't assume any particular order of execution when dealing with multiple threads. If you don't synchronize the method and have 2 threads trying to deduct from it may or may not work 999 times out of a 1000, the point is it isn't possible to predict when it will fail.

    At this case ,Because I don't use synchronized
    it must not print out error.

    because threads run at same time.

    But it prints : ERROR
    You have misunderstood what is happening. The way it will fail is as follows:

    The first thread has the execution context.
    The first thread executes the if statement and is then interrupted before subtracting the amount.
    The second thread gets the execution context.
    It executes the if statement and because the first thread hasn't deducted the amount yet the result is true.

    Now at this point both threads are waiting to execute the subtract amount code and so will both deduct all the money from the account creating a negative account value.

    If you run the code many times you will probably find it works some times and not others.

    If you use synchronized then it will never fail.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured