Java uses the synchronized cosmetic method to synchronize the instance demo of a thread _java

Source: Internet
Author: User

In Java, you can use keyword synchronized for thread synchronization control, to achieve sequential access to critical resources, and to avoid problems such as data inconsistency caused by multithreading concurrency. The principle of synchronized is the object Monitor (lock), and only the thread that gets the monitor can continue to execute, otherwise the thread waits for the monitor to get. Each object or class in Java has a lock associated with it, and for the object, the object's instance variable is monitored, and for the class, the class variable is monitored (a class is itself a class object, so the lock associated with the class is also an object lock). Synchronized keywords are used in two ways: Synchronized method and synchronized block. Both of these monitoring zones are associated with an introduced object, and when this monitoring area is reached, the JVM locks the reference object and releases the lock on the reference object when it leaves (the JVM releases the lock when an exception exits). Object locking is the internal mechanism of the JVM, which requires only writing a synchronization method or a synchronized block, and the JVM automatically acquires the lock or releases the lock when the monitoring area is manipulated.

Example 1

Let's take a look at the first example, in Java, the critical section of the same object, at the same time only one allowed to be accessed (both non-static synchronized methods):

 package concurrency;
    public class Main8 {public static void main (string[] args) {The 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 ();
    Bankthread.start ();
      The try {//join () method waits for the two threads to complete 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;
    /* Add incoming data to the balance balance/public synchronized void Addamount (double amount) {double tmp = balance;
    try {thread.sleep (10);
    catch (Interruptedexception e) {e.printstacktrace ();
    } tmp + + amount;
  balance = tmp;
    /* * to deduct incoming data from the balance balance/public synchronized void Subtractamount (double amount) {double tmp = balance;
    try {thread.sleep (10);
    catch (Interruptedexception e) {e.printstacktrace ();
    } tmp-= amount;
  balance = tmp;
  Public double GetBalance () {return balance;
  The public void setbalance (double balance) {this.balance = balance; }
}

* * Bank
implements runnable{private account
  ;
  Public Bank: {
    this.account = account;
  }
  @Override public
  Void Run () {for
    (int i = 0; i < i++) {
      account.subtractamount (1000);
    }
  }
}

/* Company * *
implements runnable{
  private account;
  Public company [Account Account] {
    this.account = account;
  }
  @Override public
  Void Run () {for
    (int i = 0; i < i++) {
      account.addamount (1000);
    }
  }
}

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

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

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

Example 2

Demonstrates the problem that static synchronized methods on the same object and non-static synchronized methods can be accessed by multiple threads at the same point in time.

 package concurrency;
    public class Main8 {public static void main (string[] args) {The 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 ();
    Bankthread.start ();
      The try {//join () method waits for the two threads to complete companythread.join ();
      Bankthread.join ();
    System.out.printf ("Account:final Balance:%f\n", account.getbalance ());
    catch (Interruptedexception e) {e.printstacktrace (); }
  }
}

 * * Account/class account{/* here to static variable * * private static double balance = 0; /* Add incoming data to the balance balance, note that the static modified/public static synchronized void Addamount (double amount) {Double tmp = balance
    ;
    try {thread.sleep (10);
    catch (Interruptedexception e) {e.printstacktrace ();
    } tmp + + amount;
  balance = tmp;
    /* * to deduct incoming data from the balance balance/public synchronized void Subtractamount (double amount) {double tmp = balance;
    try {thread.sleep (10);
    catch (Interruptedexception e) {e.printstacktrace ();
    } tmp-= amount;
  balance = tmp;
  Public double GetBalance () {return balance;
  The public void setbalance (double balance) {this.balance = balance; }
}

* * Bank
implements runnable{private account
  ;
  Public Bank: {
    this.account = account;
  }
  @Override public
  Void Run () {for
    (int i = 0; i < i++) {
      account.subtractamount (1000);
    }
  }
}

/* Company * *
implements runnable{
  private account;
  Public company [Account Account] {
    this.account = account;
  }
  @Override public
  Void Run () {for
    (int i = 0; i < i++) {
      account.addamount (1000);
    }
  }
}

I just added the static keyword to balance in the last example, and the Addamount () method can also be modified by the static keyword. The results of implementation can be tested by ourselves, each execution is a different result!

Some summary:

    The
    • synchronized is implemented through software (JVMS) and is widely used even after JDK5 has lock. The
    • synchronized is actually unfair, the new thread is likely to get the monitor immediately, while the waiting thread in the wait area may wait again, but this preemptive way can prevent starvation.
    • synchronized only the lock is associated with a condition (whether to acquire a lock) and is inflexible, and later the combination of condition and lock solves the problem.
    • When multiple threads compete for a lock, the rest of the unlocked thread can only try to acquire the lock without interruption. High concurrency can lead to performance degradation. Reentrantlock's lockinterruptibly () method gives priority to response outages. A thread waits too long, it can interrupt itself, and then Reentrantlock responds to the interrupt and stops the thread from waiting. With this mechanism, the use of reentrantlock does not produce a deadlock like synchronized.

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.