java programming multithreaded concurrent processing instance parsing

  • 2021-01-02 21:49:32
  • OfStack

This paper mainly demonstrates java programming multi-threaded concurrent processing scenario through an example of a bank user withdrawing money, as follows.

Start with an example: implement an example code of a bank account withdrawal scenario.

The first class: ES7en.java

Account type:


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: ES15en.java

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() + " When the money is withdrawn successfully, the banknote is dished out: " + drawAmount);
			//       try{ 
			//         Thread.sleep(1); 
			//       } 
			//       catch(InterruptedException e){ 
			//         e.printStackTrace(); 
			//       } 
			account.setBalance(account.getBalance() - drawAmount);
			System.out.println("\t  The balance of   :  " + account.getBalance());
		} else 
		        System.out.println(getName() + " Failed to withdraw money, insufficient balance! ");
		//   }
	}
	public static void main(String[] args){
		Account acct = new Account("123456",1000);
		new DrawThread("A",acct,800).start();
		new DrawThread("B",acct,800).start();
	}
}

Comments in the code above :(1) synchronized synchronization block and (2) thread sleep. If (1) and (2) are commented out, there are many possibilities for the operation result, and the probability is 1 (with low probability), which conforms to the normal logic:

B successfully withdraw money, spit out note: 800.0
The balance is 200.0
A failed to withdraw money, insufficient balance!

It should be B who first finds the money withdrawal resource by force and corrects the balance, then A begins to judge the user balance. This probability is very small, and most operations will resemble the following:

A successfully withdraw money, spit out note: 800.0
B successfully withdraw money, spit out note: 800.0
Balance: -600.0
The balance is 200.0

This is obviously illogical. It can be guessed from the running result that A preempts the resource first and takes out the amount, but before modifying the balance, the resource is preempted by B. Since the balance has not been modified, B sees that the balance is still 800, and B still takes out the amount; A first runs to modify the balance, but does not print, B grabs resources; B modified the balance and printed the balance to -600; The balance of A printing is 200;

If (2) thread sleep is added, 1 is an error condition because A or B will release CPU resources for sleep and JVM will call other processes in the ready state after pulling out the amount. The second withdrawal judgment balance 1 is wrong.

If (1) synchronized synchronization block is added, account is locked in the thread run method body; The execution logic is guaranteed to be normal each time:

A successfully withdraw money, spit out note: 800.0
The balance is 200.0
B failed to withdraw money, insufficient balance!
Imagine the following execution process:

A preempts resources and locks the account class at the beginning of the body of run method. The synchronization block is then executed; If the execution reaches some intermediate link, CPU resources are preempted by B; B starts execution, and the account class is also locked at the beginning of 1. However, when the lock is placed, account is already occupied by A, so it will be adjusted to block and wait for A to release the resource. A releases the lock of account after executing the synchronized code block, and B continues to execute; The balance guarantee that B sees when it runs is the one that A has modified and is executed logically.

conclusion

That is the end of this article on java programming multithreaded concurrent processing instance parsing, I hope to help you. Interested friends can continue to refer to other related topics in this site, if there is any deficiency, welcome to comment out. Thank you for your support!


Related articles: