Thread synchronization based on the use of synchronized implementation synchronization method

Source: Internet
Author: User

Java's most basic way of synchronizing is to use the Synchronized keyword to control concurrent access to a method. Each method declared with the Synchronized keyword is a critical section. In Java, the critical section of the same object, at the same time, only one allowed to be accessed.

Static methods have different behaviors. Static methods declared with the Synchronized keyword can only be accessed by one thread of execution, but other threads have access to the non-static synchronized method of the object. You must be very cautious about this because two threads can access two different synchronized methods for an object at the same time, that is, one is a static synchronized method and the other is a non-static synchronized method. If all two methods change the same data, there will be errors with inconsistent data.

Let's start with the first example, in Java, the critical section of the same object, with only one access allowed at a time (both non-static synchronized methods):

package concurrency;public class main8 {    public static  Void main (String[] args)  {        account account  = new account ();         account.setbalance (1000);         company company = new company (account);         thread companythread = new thread (company) ;         bank bank = new bank (account);         thread bankthread = new thread (Bank);         system.out.printf ("account : initial balance:   %f\n ",  account.getbalance ());         companythread.start ();      &nbSp;  bankthread.start ();        try {    The          //join () method waits for these two threads to finish running              companythread.join ();             bankthread.join ();             system.out.printf ("account : final balance:  %f\n",  Account.getbalance ());        } catch  (InterruptedException  e)  {            e.printstacktrace ();         }    }}/* Account */class account{     private double balance;    /* adds the incoming data to the balance balance */     public synchronized void&Nbsp;addamount (double amount) {        double tmp =  balance;        try {             thread.sleep (Ten);        }  catch  (interruptedexception e)  {             e.printstacktrace ();        }         tmp += amount;        balance =  tmp;    }    /* to deduct the incoming data from the balance balance */     Public synchronized void subtractamount (Double amount) {         double tmp = balance;        try  {     &nbsP;      thread.sleep (Ten);        }  catch  (interruptedexception e)  {             e.printstacktrace ();        }         tmp -= amount;        balance =  tmp;    }    public double getbalance ()  {         return balance;    }     public void setbalance (double balance)  {         this.balance = balance;    }}/* Bank */class bank implements  Runnable{    private account account;    public bank ( Account account) {&NBSP;&NBsp;      this.account = account;    }      @Override     public void run ()  {         for  (int i = 0; i < 100; i++)  {             account.subtractamount (;   )      }    }}/* company */class company implements  Runnable{    private account account;    public company (Account account) {        this.account = account;    }      @Override     public void run ()  {         for  (int i = 0; i < 100; i++)  {             account.addamount (;   )      }    }}

You have developed a simulation application for a bank account that can recharge and deduct the balance. This program will recharge the account by calling 100 times Addamount () method, deposit 1000 each time, then deduct the account balance by calling 100 times Subtractamount () method, each deduction 1000; we expect the final balance of the account to be equal to the initial balance. We implemented it through the Synchronized keyword.

If you want to see concurrent access issues with shared data, you only need to remove the synchronized keywords from the Addamount () and Subtractamount () method declarations. In the absence of the Synchronized keyword, the printed balance value is inconsistent. If you run this program multiple times, you will get different results. Because the JVM does not guarantee the order in which threads are executed, each time the thread runs, the threads will read in a different order and modify the balance of the account, resulting in a difference in the end result.

The method of an object is declared with the Synchronized keyword and can only be accessed by one thread. If thread A is executing a synchronous method Syncmethoda (), thread B will execute another synchronization method Syncmethodb () for this object, and thread B is blocked until thread a accesses the end. However, if thread B accesses a different object of the same class, then two threads are not blocked.

Example 2, demonstrates that the static synchronized method on the same object and the non-static synchronized method can be accessed by multiple threads at the same point in time to verify the problem.

package concurrency;public class main8 {    public static  Void main (String[] args)  {        account account  = new account ();         account.setbalance (1000);         company company = new company (account);         thread companythread = new thread (company) ;         bank bank = new bank (account);         thread bankthread = new thread (Bank);         system.out.printf ("account : initial balance:   %f\n ",  account.getbalance ());         companythread.start ();      &nbSp;  bankthread.start ();        try {    The          //join () method waits for these two threads to finish running              companythread.join ();             bankthread.join ();             system.out.printf ("account : final balance:  %f\n",  Account.getbalance ());        } catch  (InterruptedException  e)  {            e.printstacktrace ();         }    }}/* Account */class account{     /* here to the static variable */    private static double balance =  0;    /* Add the incoming data to the balance balance, note that the */    public static synchronized void addamount is modified with static (double  amount) {        double tmp = balance;         try {             thread.sleep (;        } catch ) ( Interruptedexception e)  {             E.printstacktrace ();        }         tmp += amount;        balance = tmp;     }    /* to deduct the incoming data from the balance balance */    public  Synchronized void subtractamount (Double amount) {         double tmp = balance;        try {             thread.sleep (;        } catch ) ( Interruptedexception e)  {             E.printstacktrace ();        }         tmp -= amount;        balance = tmp;     }    public double getbalance ()  {         return balance;    }    public  void setbalance (double balance)  {         this.balance = balance;    }}/* Bank */class bank implements runnable {    private accoUnt account;    public bank (Account account) {         this.account = account;    }     @Override     public void run ()  {        for   (int i = 0; i < 100; i++)  {             account.subtractamount (;      )   }    }}/* company */class company implements runnable{     private account account;    public company (Account account ) {        this.account = account;    }      @Override     public void run ()  {         for  (int i = 0; i < 100; i++)  {             account.addamount (;      )   }    }}

I'm just adding the static keyword to the previous example, and the Addamount () method can also be modified with the static keyword balance. Implementation results you can test yourself, each execution is a different result!

The Synchronized keyword reduces the performance of your application, so it can only be used on methods that require modification of shared data in a concurrency scenario. If multiple threads access the same synchronized method, only one thread can access it, and the other threads will wait. If the method declaration does not use the Synchronized keyword, all threads can execute the method at the same time, thus reducing the total run time. If a method is known not to be called by a thread, it does not need to be declared with the Synchronized keyword.

Methods that are declared by synchronized can be called recursively. When a thread accesses a synchronous method of an object, it can also invoke other synchronous methods of the object, and it also contains the method being executed, without having to get access to the method again.

We can protect the access of the block of code (not the entire method) by synchronized the keyword. This should be done using the Synchronized keyword: The remainder of the method remains outside the synchronized code block for better performance. Critical sections (that is, blocks of code that can only be accessed by one thread at a time) should be accessed as short as possible. For example, in the operation of obtaining a building number, we only use the Synchronized keyword to protect the instructions for updating the number of people, and let other operations not use shared data. When you use the Synchronized keyword in this way, you must refer to the object reference as an incoming parameter. Only one thread at a time is allowed access to this synchronized code. In general, we use the This keyword to refer to the object to which the method being executed belongs:

Synchronized (this) {//java code}


Thread synchronization based on the use of synchronized implementation synchronization method

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.