This article mainly demonstrates the Java programming multi-threaded concurrent processing scenario through an example of bank users withdrawing money, as follows.
Start with an example: implement the example code for a bank account withdrawal scenario.
The first class: Account.java
Account category:
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 != null && obj.getClass() == Account.class){Account target = (Account)obj;return target.getAccountNo().equals(accountNo);}return false;}} The second class: DrawThread.java
Money withdrawal 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() + "Get money successfully, spit out the banknotes: " + drawAmount);// try{ // Thread.sleep(1); // } // catch(InterruptedException e){ // e.printStackTrace(); // } account.setBalance(account.getBalance() - drawAmount); System.out.println("/t The balance is: " + account.getBalance());} else System.out.println(getName() + "Get withdraw money failed, the balance is insufficient!");// }}public static void main(String[] args){Account acct = new Account("123456",1000);new DrawThread("A",acct,800).start();new DrawThread("B",acct,800).start();}} The commented out part in the above code: (1) Synchronized synchronization code block (2) Thread hibernation. If (1) and (2), there are many possibilities for the run result, one of the possibilities (the probability is small), which conforms to normal logic:
B successfully withdraws money, spits out the money: 800.0
Balance is: 200.0
A failed withdrawal and the balance was insufficient!
It should be that B first finds the money withdrawal resource and modifys the balance correctly before A starts to judge the user balance; this probability is very small, and most operations will be similar to the following situations:
A successfully withdraws money and spits out the money: 800.0
B successfully withdraws money, spits out the money: 800.0
Balance is: -600.0
Balance is: 200.0
This is obviously illogical. From the running results, we can guess that A first seizes the resource and withdraws the amount, but before modifying the balance, the resource is seized by B; since the balance has not been modified, B sees that the balance is still 800, and B still withdraws the amount; A first runs the modification balance, but does not print it, B snatches the resource; B modifys the balance and prints the balance, which is -600; A prints the balance, which is 200;
If (2) thread sleeps, it must be an error condition, because A or B will release CPU resources due to sleep after fetching the amount, and the JVM will call other processes in the ready state. The second thing is to withdraw money and judge the balance must be wrong.
If (1) synchronized synchronized code block is added, the account is locked in the thread run method body; then the execution logic will be guaranteed to be normal every time:
A successfully withdraws money and spits out the money: 800.0
Balance is: 200.0
B failed to withdraw money, and the balance was insufficient!
You can imagine the execution process:
A first preempts the resource and locks the account class initially in the run method body; then starts executing the synchronous code block; if it is executed to a certain link in the middle, the CPU resource is preempted by B; B starts executing, and locks the account class at the beginning. However, when adding a lock, you will find that the account has been occupied by A, and it will be adjusted to a blocking state and wait for A to release the resource; after A has executed the synchronous code block, the account lock will be released, and B will continue to execute; the balance seen during running B is guaranteed to be modified by A and will be executed normally according to the correct logic.
Summarize
The above is all the content of this article about the analysis of multi-threaded concurrent processing instances of Java programming, and I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!