Before you say anything, what is a thread?
Thread: It's a task fragment.
Process: A program that has a separate function to run an activity on a data set, one or more threads in a process
The essential difference between a thread and a process is that there is data sharing space, data can be shared between threads, and processes can not
Enter the following topic: synchronization between threads
As business processes increase and business nodes increase, the number of people using the business increases at the same time, inevitably concurrency problems occur, and multiple threads concurrently access operations on a single unit of data
We use bank transfer as an example to illustrate the following code:
The establishment of a bank of the class, which consists mainly of three methods, one is the transfer, one is to get the total number of existing bank deposits, one is to obtain the current number of depositors
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, because concurrent operations are required, so implementing 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 is the test class:
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 after the first second transfer, the total number was wrong, and the results were carefully observed, due to the parallel execution of the task, and the middle due to the CPU allocation execution order, so we see the results are not exactly the way we implemented the output
As a result of this problem, we introduce the concept of "lock", because this is an analysis, not for the lock details, the following we in the bank of the transfer method above with the simplest and most commonly 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 due to my data accuracy problem, follow-up can be avoided by other settings.
The program inside because of the lock, so in the performance of the inevitable decline, especially in some large programs inside, so this need according to the actual business needs, lock the range of locks to a relatively small range, so that performance will not be significantly reduced.
Finally, let's summarize the above-mentioned things into a diagram.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Getting Started with Java Basics-Multithreading synchronization-taking bank transfers as an example