Java Multi-Threading synchronization mechanism (synchronized)

Source: Internet
Author: User

A piece of synchronized code is executed by a thread before he gets the permission to execute this code, in Java is the lock that gets a synchronization object (one object has only one lock); If the lock of the synchronization object is taken away by another thread at this time, He (this thread) can only wait (threads are blocked in the lock pool wait queue). After the lock is taken, he begins to execute the synchronization code (the code that is synchronized decorated), and the thread executes the synchronization code immediately after it has been executed, and the other thread that waits in the lock pool can get the lock to execute the synchronization code. This ensures that only one thread is executing at the same time in the synchronization code.

As we all know, in Java multithreaded programming, a very important aspect is the thread synchronization problem.
With regard to thread synchronization, the following workarounds are generally available:

1. Add the Synchronized keyword to the method signature of the method that requires synchronization.

2. Use the synchronized block to synchronize the code snippets that need to be synchronized.

3. Use the lock object from the Java.util.concurrent.lock package provided in JDK 5.

In addition, in order to solve the security problems that can occur when multiple threads access the same variable, we can not only adopt the synchronization mechanism, but also ensure better concurrency through the threadlocal added in JDK 1.2.

In this article, we will discuss the Java multithread Synchronization mechanism in detail, and discuss the threadlocal.

The approximate directory structure of this article is as follows:

First, the thread of the first served-the question of the proposed: why should have multi-thread synchronization? What is the mechanism of Java multithreaded synchronization?
Two, give me a lock, I can create a rule--what is the traditional multi-threaded synchronous programming method? What are their similarities and differences?
Three, lock came, we all move aside--java the lock in the concurrency framework.
Four, you have I have all have--threadlocal how to solve concurrency security?
V. Summarize several methods of--java thread safety comparison.


First, the first served of the thread

Let's give an example of a dirty: a restaurant has a small bathroom that can barely hold a person to the toilet. In order to ensure uninterrupted, toilet people into the bathroom, it is necessary to lock the door. We can think of the bathroom as a shared resource, and many people who need to get to the toilet can be seen as multiple threads. If the bathroom is currently occupied, then other people must wait until the person has finished the toilet and opens the door to come out. This is like when multiple threads share a resource, they must be first served.

Someone said, "What if I don't have the door?" Let two threads compete with each other, who first, who can work, so much good? But we know: if there is no door in the toilet, the people who go to the toilet together to the toilets, then there will inevitably be a dispute, the normal toilet steps will be disrupted, there is likely to be unexpected results, such as some people may have to be forced to fertilize in the wrong place ...

It is because of this door that any individual who goes to the toilet can successfully complete their toilet process without being disturbed or even outside of the results. This means that you should pay attention to first served when you go to the toilet.


So how can you ensure that there is no "fight" when multiple threads compete for the same resource in a Java multithreaded scenario? Some say the use of a synchronization mechanism. Yes, like the example above, a typical synchronization case, once the first one begins to go to the toilet, the second must wait for the first to end before he can begin the toilet process. A thread, once in a process, must wait for a normal return and exit the process before the next thread can begin the process. Here, the key is the bathroom door. In fact, the door of the bathroom is the role of the resource lock, as long as the people who are going to the toilet lock the door, it is equivalent to obtain the lock, and when he opened the lock, it is equivalent to release the lock.

In other words, the thread synchronization mechanism of multithreading is actually controlled by the concept of lock. So in Java programs, how does a lock show?


Let's look at the concept of lock from the JVM's point of view:

In the Java Program Runtime environment, the JVM needs to reconcile the data shared between the two types of threads:
1) instance variables saved in the heap
2) class variables saved in the method area

These two types of data are shared by all threads.
(The program does not need to reconcile the data stored in the Java stack.) Because this data is owned by the thread that owns the stack. )

In a Java virtual machine, each object and class is logically associated with a single monitor.
For an object, the associated monitor protects an instance variable of the object.

For classes, the monitor protects class variables for classes.

(If an object does not have an instance variable, or if a class has no variables, the associated monitor is not monitored at all.) )
To achieve the exclusive monitoring capabilities of the monitor, the Java Virtual Machine Associates a lock for each object and class. Represents a privilege that only one thread is allowed to have at any time. A thread accesses an instance variable or class variable without a lock.

But if a thread acquires a lock, no other thread can get a lock on the same data until it releases the lock. (Locking an object is the monitor that gets the object associated with it)

Class locks are actually implemented with object locks. When a virtual machine loads a class file, it creates an instance of the Java.lang.Class class. When you lock an object, the class object is actually locked.

A thread can lock the same object multiple times. For each object, the Java Virtual Machine maintains a lock counter, each time the thread obtains the object, the counter adds 1, each time it is released, the counter is reduced by 1, and when the counter value is 0 o'clock, the lock is completely released.

Java programmers do not need to do their own locking, object locks are used inside the Java Virtual machine.

In a Java program, you only need to use the synchronized block or the Synchronized method to flag a monitoring area. The Java Virtual machine locks the object or class automatically each time you enter a monitoring area.

See here, I think you must all tired of it? O (∩_∩) o ... Ha ha. Let's take a break, but before you do, you must remember:
When a limited resource is shared by multiple threads, in order to guarantee mutually exclusive access to the shared resources, we must give them a first served. To do this, the object lock plays a very important role here.

In the previous article, we talked about how multithreading handles shared resources, and the important mechanism on which they rely on mutually exclusive access to resources: Object locks.



In this article, let's take a look at the traditional synchronous implementation and the rationale behind it.



Many people know that in Java multithreaded programming, there is an important keyword, synchronized. But a lot of people will be confused when they see this: "All say that the synchronization mechanism is implemented by object lock, but I can't see which object the Java program has locked." “


Yes, I was also puzzled and puzzled at the beginning of the problem. But fortunately, we have the following routine:

Java code
  1. Public class ThreadTest extends Thread {
  2. private int threadno;
  3. Public threadtest (int threadno) {
  4. This.threadno = Threadno;
  5. }
  6. public static void Main (string[] args) throws Exception {
  7. For (int i = 1; i < i++) {
  8. New ThreadTest (i). Start ();
  9. Thread.Sleep (1);
  10. }
  11. }
  12. @Override
  13. public synchronized Void Run () {
  14. For (int i = 1; i < 10000; i++) {
  15. System.out.println ("No." + Threadno + ":" + i);
  16. }
  17. }
  18. }

This program actually lets 10 threads count from 1 to 9999 on the console. Ideally, we would like to see a thread count and then another thread to start counting. But the execution of the program tells us that these threads are still in a mess where there is no rule whatsoever.
But the attentive reader notes that the Run method adds a synchronized keyword, which, by reason, should be executed one after the other to execute the Run method.
However, in the previous article, we mentioned that for a member method plus the Synchronized keyword, this is actually the object lock that the member method resides on. In this case, it is a specific object of the ThreadTest class, that is, the thread itself as an object lock. A total of 10 threads, each of which holds the object lock of its own thread object. This must not produce a synchronous effect. In other words, if these threads are to be synchronized, the object locks held by those threads should be shared and unique!

Let's take a look at the following routines:

Java code
  1. public class ThreadTest2 extends Thread {
  2. private int threadno;     private String lock;
  3. Public ThreadTest2 (int threadno, String lock) {
  4. This.threadno = Threadno;
  5. This.lock = lock; }     
  6. public static void Main (string[] args) throws Exception {
  7. String lock = new String ("lock");
  8. For (int i = 1; i < i++) {
  9. New ThreadTest2 (I, Lock). Start ();
  10. Thread.Sleep (1);
  11. }
  12. }
  13. Public void Run () {
  14. synchronized (lock) {
  15. For (int i = 1; i < 10000; i++) {
  16. System.out.println ("No." + Threadno + ":" + i);
  17. }
  18. }
  19. }
  20. }

We noticed that the program created a string object by starting 10 threads before the main method. And through the ThreadTest2 constructor, this object is assigned to each THREADTEST2 thread object in the private variable lock. According to the characteristics of the Java method, we know that the lock variable of these threads actually points to the same area in the heap memory, that is, the area that holds the lock variable in the main function.
The program removes the Synchronized keyword before the previous run method and uses a synchronized block in the run method to implement it. The object lock for this synchronization block is the string object created in the Main method. In other words, they point to an object of the same string type, and the object lock is shared and unique!

So, we see the expected effect: 10 threads are no longer scrambling to count off, but one after the count.

Then look at the following routines:

Java code
  1. Public class ThreadTest3 extends Thread {
  2. private int threadno;
  3. private String lock;
  4. Public ThreadTest3 (int threadno) {
  5. This.threadno = Threadno;
  6. }
  7. public static void Main (string[] args) throws Exception {
  8. For (int i = 1; i < ; i++) {
  9. New ThreadTest3 (i). Start ();
  10. Thread.Sleep (1);
  11. }
  12. }
  13. public static synchronized void abc (int threadno) {
  14. For (int i = 1; i < 10000; i++) {
  15. System.out.println ("No." + Threadno + ":" + i);
  16. }
  17. }
  18. public Void Run () {
  19. ABC (THREADNO);
  20. }
  21. }

  • The careful reader finds that this code does not use the string object created in the main method as the thread lock for these 10 threads. Instead, thread synchronization is achieved by invoking a static synchronization method ABC in the Run method in this thread. I want to see here, you should be very confused: here synchronized static method is to use what to do object lock?



    We know that for a synchronous static method, the object lock is the class instance of the classes in which the static drop is located, because in the JVM, all the loaded classes have a unique class object, specifically in this case, the only Threadtest3.class object. No matter how many instances of the class we have created, its class instance is still one!



    So we know:

    1, for synchronous methods or blocks of code, must obtain an object lock to be able to enter the synchronization method or code block to operate;


    2, if you are using method-level synchronization, The object lock is the object that the method resides in, and if it is a static method, the object lock refers to the
    Class object (unique) where method is located;


    3, for code blocks, the object lock refers to ABC in synchronized (ABC);


    4, because in the first case, the object lock is every thread object, so there are multiple, so the synchronization fails, the second common object lock lock, so the synchronization takes effect, and the third because it is the
    static object lock is ThreadTest3 class object, So the synchronization takes effect.

    If the above is correct, there are two ways to synchronize, synchronous blocks and synchronous methods (why not wait and notify?). I'll explain this in the Supplemental section)

    If the code block is synchronized, the object lock needs to be specified by the programmer itself, and generally some code is synchronized (this) only in the case of single-state mode;
    (instances of this class have only one)

    In the case of synchronous methods, the is static and non-static, both  .

    Static methods are bound to be synchronized, non-static methods need to be in the singleton mode to take effect, it is recommended to use static methods (do not worry about whether or not singleton).

    So, in Java multithreaded programming, the most common synchronized keyword actually relies on the mechanism of object locking to implement thread synchronization.
    We seem to be able to hear synchronized saying to us, "Give me a   lock, I can create a rule."

Transfer from https://www.cnblogs.com/gavin110-lgy/p/5716421.html

Java Multi-Threading synchronization mechanism (synchronized)

Related Article

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.