Getting Started with Java Basics-Multithreading synchronization-taking bank transfers as a sample

Source: Internet
Author: User

Before you say anything, what is a thread?

Thread: It's a task fragment.

Process: is an execution activity of a program with independent functionality about a data collection. A process has one or more threads


The essential difference between a thread and a process is that there is a data-sharing space. Data can be shared between threads. Process can not


The following entry topics: synchronization between threads

Because business processes are now added. The business node is also added. The people who use the business are also added at the same time. It is inevitable that concurrency problems occur at this time, and multiple threads visit the same time to operate a single data unit

We use bank transfer as an example to illustrate the following code:

The establishment of a bank of the class, which mainly contains three methods, one is the transfer, one is to get the total number of existing bank deposits, one is to get the number of depositors today

public class Bank {private final double[] accounts;public Bank (int n, double initialbalance) {accounts = new double[n];for (int i = 0; i < accounts.length; i++) {Accounts[i] = initialbalance;}} public void transfer (int from, int to, double amount) {if (Accounts[from] < amount) {return;} System.out.println (Thread.CurrentThread ()); Accounts[from]-= amount; System.out.printf ("%f from%d to%d", amount, from, to); Accounts[to] + = amount; System.out.println ("total:" + gettotalbalance ());} Public double gettotalbalance () {Double sum = 0d;for (int i = 0; i < accounts.length; i++) {sum + = accounts[i];} return sum;} public int getaccountsize () {return accounts.length;}}


The following is the transfer class, due to concurrent operation. So implement the Runnable interface


public class Transferrunnable implements Runnable {private Bank bank;private int fromaccount = 0;private double Maxamount = 0;public Transferrunnable (Bank b, int fromaccount, double maxamount) {This.bank = B;this.fromaccount = Fromaccount;this. Maxamount = Maxamount;}  @Overridepublic void Run () {Double amount = Maxamount * math.random (); int toaccount = (int) ((int) bank.getaccountsize () * Math.random ()); Bank.transfer (Fromaccount, Toaccount, amount); try {Thread.Sleep ((long) (100L * Math.random ())} catch (Interruptedexception e) {//TODO auto-generated catch Blocke.printstacktrace ();}}}

Here are the test classes:

public class Test {public static void main (string[] args) {Bank Bank = new Bank (+ +); for (int i = 0; i < 3; i++) {transferrunnable transferrunnable = new Transferrunnable (bank, i,1000); Thread thread = new Thread (transferrunnable); Thread.Start ();}}}

Output Result:

Thread[thread-0,5,main]
Thread[thread-2,5,main]
Thread[thread-1,5,main]


430.796266 from 0 to 75

714.274395 from 1 to 88

849.880218 from 2 to 33


total:98435.8453871716
total:99150.11978192833
total:100000.0

We looked at the results above, especially the total totals for the last three lines, and found that the total number was incorrect after the first second transfer. Careful observation of the print results because the tasks are run in parallel, and the middle because the CPU is assigned the run order. So the results we're seeing are not output exactly as we did in our approach.

Because of this problem, we introduce the concept of "lock". Because this is an analysis, it is not specific to the lock, the following we in the bank of the transfer method above plus the simplest and most frequently used lock synchronized, to see how the results:

public class Bank {private final double[] accounts;public Bank (int n, double initialbalance) {accounts = new double[n];for (int i = 0; i < accounts.length; i++) {Accounts[i] = initialbalance;}} Added lock public synchronized void transfer (int from, int. to, double amount) {if (Accounts[from] < amount) {return;} System.out.println (Thread.CurrentThread ()); Accounts[from]-= amount; System.out.printf ("%f from%d to%d", amount, from, to); Accounts[to] + = amount; System.out.println ("total:" + gettotalbalance ());} Public double gettotalbalance () {Double sum = 0d;for (int i = 0; i < accounts.length; i++) {sum + = accounts[i];} return sum;} public int getaccountsize () {return accounts.length;}}


Output Result:

Thread[thread-0,5,main]
187.754955 from 0 to total:100000.0


Thread[thread-1,5,main]
282.138799 from 1 to total:100000.0


Thread[thread-2,5,main]
217.089515 from 2 to total:100000.00000000001


The above output is basically consistent, the last result is a decimal problem, mainly because of my data accuracy problem, perhaps can be avoided by other settings.


In the program because of the lock, so the performance above the inevitable decline, especially in some large programs inside. So it needs to be based on the actual business needs, lock the range of locks to a smaller range, so that performance will not be significantly reduced.


Finally, let's summarize the above-mentioned things into a diagram.





Getting Started with Java Basics-Multithreading synchronization-taking bank transfers as a sample

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.