When multiple threads are used to access the same data, there is a risk of thread-safety issues. For example, the bank takes money. When we go to the ATM to withdraw money, just another person transfer, that is, multiple threads to modify the same data, it is prone to thread safety issues.
Thread Safety
/** * Account class, this class encapsulates the account number and balance two properties * @author Emily-t * */public class Account {//Accounts number private String accountno;//balance private double b Alance;public account () {}//constructor public account (String accountno,double balance) {this.accountno = Accountno; This.balance = balance;} The following two methods calculate the account's hashcode and judgment according to Accountno Equalspublic int hashcode () {return Accountno.hashcode ();} public boolean equals (Object obj) {if (obj! = null && obj.getclass () = = Account.class) {Account target = (account) Obj;return Target.getaccountno (). Equals (Accountno);} return false;} Public String Getaccountno () {return accountno;} public void Setaccountno (String accountno) {this.accountno = Accountno;} Public double GetBalance () {return balance;} public void setbalance (double balance) {this.balance = balance;}} /** * Take money Thread class * * @author emily-t * */public class Drawthread extends Thread {//Impersonate user account private accounts account;//current fetch thread The amount of money to look for private double drawamount;public Drawthread (String name, account account, double drawamount) {super (name);This.account = Account;this.drawamount = Drawamount;} Data security issues will be involved when multiple threads modify the same shared data public void run () {////account balance greater than the amount of money if (account.getbalance () >= drawamount) {// Spit out the banknote System.out.println ("Take money!") Spit Money: "+ drawamount);//try {//thread.sleep (1);/} catch (Interruptedexception e) {//e.printstacktrace ();//}// Modify Balance Account.setbalance (Account.getbalance ()-drawamount); System.out.println ("\ t balance is:" + account.getbalance ());} else {System.out.println (GetName () + "failed to withdraw money! Insufficient balance! ");}}} /** * Start Two threads * @author emily-t * */public class Testdraw {public static void main (string[] args) {//Create an account accounts acct = NE W Account ("1234567", 1000);//Simulate two threads to withdraw money from the same accounts new Drawthread ("a", acct,800). Start (); New Drawthread ("B", acct,800). Start ();}}
Results:
as a result, the account balance is only + , remove the the Yuan, the rest -200 Yuan. This result occurs because The method body of the Run method does not have synchronization security, and there are two concurrent threads in the program that are modifying the account object.
Thread Synchronization
Modify the following: Add the synchronization code block:
When multiple threads modify the same shared data, it involves data security issues public void run () {/////Using account as the synchronization monitor, before any thread enters the following synchronization code block, it must first obtain//lock-out of accounts-other threads cannot get locks, That is, cannot modify it//locking--Modify complete--release lock synchronized (account) {///balance greater than the amount of money to withdraw if (account.getbalance () >= drawamount) {// Spit out the banknote System.out.println ("Take money!") Spit Money: "+ drawamount"; try {thread.sleep (1);} catch (Interruptedexception e) {e.printstacktrace ();} Modify Balance Account.setbalance (Account.getbalance ()-drawamount); System.out.println ("\ t balance is:" + account.getbalance ());} else {System.out.println (GetName () + "failed to withdraw money! Insufficient balance! ");}}}
Results:
Only one thread can get a lock on the synchronization monitor at any time, and when the synchronization code block executes, the thread naturally releases the lock on that synchronization monitor.
Purpose of the synchronization monitor: prevents two threads from concurrently accessing the same shared resource. Therefore, it is generally recommended to use shared resources that may be concurrently accessed as synchronization monitors.
in order to reduce the negative effect of program security, the thread safety of variable class is to reduce the running efficiency of the program, the program can adopt the following strategy:
1 , do not synchronize all methods of the thread-safe class, only those methods that will change the competing resources
2 , if the mutable class has two running environments: single-threaded and multithreaded, you should provide two versions of the mutable class: The thread-unsafe version and the thread-safe version. Thread-safe versions are used in a multithreaded environment to ensure performance in a single-threaded environment, using an unsafe version of threads.
Multithreaded Programming (iv)--thread synchronization