J2SE Fast Advanced-multi-thread synchronized

Source: Internet
Author: User

My wife and I went to the bank to collect money

One day, and the wife played a bet, now my bank account in a total of 5000 dollars, we go to the bank at the same time to take money, to see if we can both remove 5000来 .... (PS: The price of a bet is: if you can take out 5000, then the 10000 pieces to buy her food!) If you can only take 5000, hey, that's only 5000 to buy her to eat ~ ~ ~ How to feel this condition a bit strange nie? )

The heartbeat is not as action! She took the passbook to the counter to fetch, I took the bank card to the ATM machine to take, found a suitable time, I entered a good amount, has been staring at the teller hand, he in all ready to hit the return of the car at the same time, I hit the lightning is determined. The result is, my ATM machine swish swish Spit 50 Zhang Mao Grandpa, wife side also triumphantly holding 5000 dollars come over ....
"Hey, wake up!" ”

The original is in a Dream ~ ~ No, this may work, I have to try! Do not believe, I also use just learned the thread of knowledge to verify a bit!       

public class Testdrawmoney implements Runnable {//Description: The background of this example is "multiplayer" and "simultaneous" on "Same account" withdrawals/withdrawals from Danny's account on the consolidated account depositor Danny = new Depositor ();p ublic static void Main (string[] args) {Testdrawmoney test=new Testdrawmoney ();//The operation of my withdrawal is a thread draw1, My wife's withdrawal operation is also a thread draw2thread DRAW1 = new Thread (test); Thread draw2 = new Thread (test);d raw1.setname ("i");d raw2.setname ("my Wife");//Boot Thread Draw1.start ();d Raw2.start ();}    Override the Run method public void run () {Danny. Drawmoney (5000);}} Depositor class Depositor {//balance private static int deposit = 5000;//method public void  Drawmoney (int money) {if "Money <= de POSIT) {//Analog bank System.out.println (Thread.CurrentThread (). GetName () + "withdrawals: Successful withdrawals! "+ Money +" Yuan! ");//Demo account Debit Process deposit = Deposit-money;} Else{system.out.println (Thread.CurrentThread (). GetName () + "when withdrawing money: insufficient balance!" ");}}}

If the bank withdraws the procedure similar to the above, then one of the threads (such as my wife to withdraw money) before running to "account Debit", the resources may be another thread (such as I withdraw money) to run, then the first thread because the account has been judged sufficient balance, And already gave the money to my wife, but before the bank debit run, I withdraw money this thread preemptive execution, the bank has not been deducted, so in my withdraw money this thread, judge balance is sufficient.
What do you think of the test results? We both really took out 5000!

Unfortunately learning the thread in the lock mechanism, this dream of fortune was completely broken ....

public class Testdrawmoney implements Runnable {//Description: The background of this example is "multiplayer" and "simultaneous" on "Same account" withdrawals/withdrawals from Danny's account on the consolidated account depositor danny = new depositor (); public static void Main (string[] args) {Testdrawmoney test = new Testdrawmoney ();//The operation of my withdrawal is a thread draw1, My wife's withdrawal operation is also a thread draw2thread DRAW1 = new Thread (test); Thread draw2 = new Thread (test);d raw1.setname ("i");d raw2.setname ("my Wife");//Boot Thread Draw1.start ();d Raw2.start ();} Override the Run method public void run () {Danny. Drawmoney (5000);}}  Depositor class Depositor {//balance private static int deposit = 5000;//Take money method public void Drawmoney (int money) {synchronized (this) {//Here for the entire operation of the thread plus the lock if (money <= deposit) {///analog Bank spit-up process System.out.println (Thread.CurrentThread (). GetName () + "withdrawals: Successful withdrawals! "+ Money +" Yuan! ");//Demo account Debit Process deposit = Deposit-money;} else {System.out.println (Thread.CurrentThread (). getname+ "When withdrawing money: insufficient balance! ");}}}}

The only difference from the first example is that the lock--synchronized is added to the Drawmoney () method, so that when a thread runs this method, the object is locked and other threads cannot execute the code that is locked in the method.

As a result, only one person can take the money:

Or (these two threads, first executed to be able to withdraw money, but who first who is not necessarily, so there will be two results.) )


Synchronized Introduction

When multiple threads may be accessing the same resource at the same time, consider whether to use synchronized. Synchronized is used to lock objects, methods, or blocks of code. Only one thread can execute the locked code at the same time, and no other thread will break it, it must wait until the thread that is currently executing the lock code executes and the other thread can execute.

The essence of sychronized is. In the process of executing the locked method or code, the current object is locked (since the current object "Danny" is locked in the previous example, the static variable "deposit" in the current object must also be locked).

the use of synchronized

1, with synchronized modification method, the above example can be directly modified with synchronized Drawmoney () method:     

Public synchronized void Drawmoney (int. money) {if (<= deposit) {//Analog bank spit-up process System.out.println ( Thread.CurrentThread (). GetName () + "withdrawals: Successful withdrawals" + Money + "Yuan!" ");//Demo account Debit Process deposit = Deposit-money;} else {System.out.println (Thread.CurrentThread (). GetName () + "when withdrawing money: insufficient balance! ");}}
If an object has multiple synchronized methods, as long as one thread accesses one of the synchronized methods, the other thread cannot access any of the synchronized methods in the object at the same time.

If two threads want to access this method at the same time, they need to be accessed in two instance objects. In other words, the methods of synchronized modification in different object instances do not interfere with each other.


2. Lock code with synchronized

As in the second example above, in the method, use synchronized (this) {//code fragment} to lock the code that only one thread is allowed to access at the same time. At the same time, other threads do not allow access to the locked code snippet for this object. That is, when this code snippet is executed, the current object is locked, the other threads are not allowed access, and the other threads are not accessible until the current thread has finished executing.


synchronized may cause problems

When the program is "locked", there are other problems-deadlocks.

For example, now Danny and Maria two people only have a pair of chopsticks, want to eat a big meal they only grab two chopsticks to open eat:

public class TestDeadLock2 implements Runnable {public String name;      Name static Object chopsticks1 = new Object ();      First chopsticks static Object CHOPSTICKS2 = new Object (); The second chopstick public static void Main (string[] args) {System.out.println ("Grab chopsticks start! "); TestDeadLock2 test1=new TestDeadLock2 (); TestDeadLock2 test2=new TestDeadLock2 (); Test1.name= "Danny"; test2.name= "Maria"; Thread t1=new thread (test1); Thread t2=new thread (test2); T1.start (); T2.start ();} public void Run () {if (Name.equals ("Danny")) {synchronized ("Chopsticks1") {Thread.Sleep (500);//here to enlarge the effect, Let Danny grab the chopsticks. 1 o'clock Pause} catch (Interruptedexception e) {e.printstacktrace ();} Synchronized (CHOPSTICKS2) {System.out.println ("Danny succeeds in grabbing two chopsticks, he's going to eat!") ");}}} else if (name.equals ("Maria")) {synchronized (CHOPSTICKS2) {try {thread.sleep (500);//here to enlarge the effect, let Maria grab the chopsticks 2 o'clock pause} catch (Interruptedexception e) {E.printstacktrace ();} Synchronized (CHOPSTICKS1) {System.out.println ("Maria successfully grabs two chopsticks, she's going to eat!") ");}}}}}
in the example, Danny and Maria grab each chopsticks when the chopsticks will be held in hand, when Danny grabbed chopsticks 1,maria grab chopsticks 2 o'clock, they are waiting for each other to give up chopsticks, do not give, infinite wait, this happened to deadlock.


Therefore, use the lock to be cautious, when it comes to synchronization, it is important to consider whether the thread should be synchronized, add synchronization, be inefficient, and not synchronize, possibly resulting in inconsistencies in the data in the previous example.


J2SE Fast Advanced-multi-thread synchronized

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.