Home » Java » Multithread


, Synchronized

From an example of


implementation of a bank account money scene:

first class: Account.java


package cn.edu.byr.test;
Public class {Account
Private String accountNo;
Private double balance;
Public (Account) {}
Public Account (String accountNo, double balance) {
This.accountNo = accountNo;
This.balance = balance;
Public int (hashcode) {
Return (accountNo.hashCode);
Public String (getAccountNo) {
Return this.accountNo;
Public double (getBalance) {
Return this.balance;
Public void setBalance (double balance) {
This.balance = balance;
Public Boolean equals (Object obj) {
If (this = obj)
Return true;
If (obj) and obj.getClass (null! = = = Account.class) {
Account = target (Account) obj;
Return (target.getAccountNo).Equals (accountNo);
Return false;

Second class:

money thread class:

package cn.edu.byr.test;
Public class DrawThread extends {Thread
Private Account account;
Private double drawAmount;
Public DrawThread (String name, Account account, double drawAmount) {
Super (name);
This.account = account;
This.drawAmount = drawAmount;
Public void (run) {
Synchronized (account) {/ /
If (account.getBalance) > (drawAmount) {
System.out.println ((getName) + "take money successfully, spit out the money:" + drawAmount);
/ / try{
/ / Thread.sleep (1);
} / /
Catch (InterruptedException E) {/ /
(/ / e.printStackTrace);
} / /
Account.setBalance (account.getBalance) - (drawAmount);
System.out.println ("t balance:" + (account.getBalance));
System.out.println ((getName) + "money failure, lack of balance!");
} / /
Public static void main (String[] args) {
Account acct = new Account (123456, 1000);
New DrawThread (A, acct,.Start) (800);
New DrawThread (B, acct,.Start) (800);

Comment out part of the above code: (1) synchronized code (2) thread sleep

if the comment out (1) (2),


variety of possibilities, one possibility (low probability):

with normal logic:

B take money successfully, spit out the money: 800.0

balance is 200.0
A failed to get money, the balance of the


B should be the first strong find money resources, and properly modify the balance after A to determine the user balance; this probability is very small, the majority will be similar to the following:


A take money successfully, spit out the money: 800.0

B take money successfully, spit out the money: 800.0

balance is -600.0
balance is 200.0


this is obviously not logical, the results can be speculated that A should seize the resources, the amount taken out, but changes in the balance before the resources preempted by B;

because the balance is not modified, B see the balance is still 800, B is still the amount taken out;

The first run

A modify the balance, but did not print B, grab resources;

B modify the balance, and print the balance, -600


A printing balance, 200;

If the

plus (2) threads sleep, it is wrong, because the A or B will be in the amount taken out after the release of sleep for CPU resources, JVM will call the other is in the ready state process. Second money balance judgment must be wrong.

If you add the

(1) synchronized code, the run method of account thread lock; every time will ensure the normal execution of logic:

A take money successfully, spit out the money: 800.0

balance is 200.0
B failed to get money, the balance of the


can imagine the implementation process:

A the first to seize the resources in the run method of the account class of initial lock; then begins executing code;

if the implementation of a link in the middle, CPU resources B preemption; the B is started, will start the account class lock. But the lock will find that account has been taken by the A, will be adjusted to the blocking state waiting for the release of A resources;

A executes synchronized code block after the release of account lock, B to continue; see the B runtime to ensure the balance of A has been modified, in accordance with the correct logic normal execution;