Java multi-threading should be aware of

Please talk about the underlying principle is simple synchronized keyword

When it comes to multi-threaded java absolutely not open around the synchronized, many java engineers synchronized love and hate. why? The main reasons include the following:

  1. A variety of learning materials found on the Internet, many of which are based on the content of messy old version written up their own practice and found online that is not the same, not that thing back to the children. Irritability ......

  2. Every time out the interview will ask this question, but can not look directly at the source. Fretful

  3. You will find in a small company to develop my colleagues, if it is done javaWeb projects rarely encountered multithreading problems in practical work. Because of the small amount of data, a small number of requests various reasons.

So after learning summarize this period of time (blind to see, blind push lightly), I would like to output my simple understanding of the underlying principles of the synchronized keyword.

monitor counter

Here declare a premise, synchronized is reentrant lock, that has been locked object can be acquired to lock the threads again locked again. Is not it a bit Raozui, look at the following code:

public class SynchronizedDemo {


    public static void main(String[] args) {
        SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
        synchronizedDemo.test();
    }

    public synchronized void test() {
        System.out.println("来一把锁");
        test1();
    }

    public synchronized void test1() {
        System.out.println("再次加锁");
    }
}

/* output 来一把锁 再次加锁*/

Simple to explain the code. We create an object synchronizedDemo, then call the method test, due to the synchronized modification of the method, so we will target synchronizedDemo were locked. Then, the internal test method and is called test1 method, this time we find test1 modification is synchronized, so we were locked again synchronizedDemo, this is the second lock on the object.

Here is the embodiment synchronized is reentrant lock features. Broadly reentrant lock means that can be repeated recursively lock, after the use of the outer lock, still may be used in the inner layer, and deadlock does not occur (provided that have the same object or class), such a lock called reentrant lock.

Well Closer to home, how synchronized is to do it?

In short there is a monitor underlying counter, Dangdang a thread for the first time to get an object when the object will head the counter to 1, again locked in the locked cycle, then on the basis of the original +1 again, and so on. How is this going children do?

It can be understood that such a test method of execution

  1. First, determine whether the spot synchronizedDemo object has been encrypted, that is, whether the counter to zero

  2. If you have a 1, it means the object has already been occupied by other threads, the current thread can not obtain this object, this time can only wait

  3. If the counter is 0, indicating that the object is not currently in use by another thread, the current thread can be locked. monitor counter + 1 (from 0 to 1)

  4. If additional locking method is also called locking method, each nested locking method of performing a monitor will make counter + 1, -1 method is performed again after completion.

  5. After the final synchronized modification of the method is finished, monitor counter object is zero, wait for the other threads.

Say it seems still a little fuzzy, I am here simply abstract simulate how this works roughly like this:

monitorenter  +1
  test();
        monitorenter +1
      test1();
        monitorexit; -1
monitorexit; -1

Before the implementation of test methods, monitorenter counter +1 (this time the counter value is 1, prior to obtaining this object, the object must be counter 0, or get less), then test the method in turn invokes a method test1, and this method is modified to be synchronized, then performs monitorenter counter is incremented again (this time the counter value of 2). When the method test1 been performed, the monitorexit counter value will be 1 (this is a time of 2 - 1 = 1), then the test method is performed over, and then the monitorexit -1 value of the counter, when the counter value at this time 0 is a. That is, the lock has been released, the lock object can continue to be acquired by other threads.

synchronized lock lock method is what?

I believe we all know can be synchronized lock on the objects and methods.

    Map<String, Object> map = new HashMap<>();  
    // 修饰方法
    public synchronized void test() {
        System.out.println("来一把锁");
       // 锁对象
        synchronized (map) {
            System.out.println("对 map 对象进行加锁");
        }
        test1();
    }

See here a collection of above said counter, there will be a classmate questioned.

Not to say that the first counter in the object stored inside it? That method where the lock is for added lock ah? Let me talk Conclusion: The method lock, the lock is still loaded on the object, which object calls this method, which is locked on the subject.

for example:

public class SynchronizedDemo {


    HashMap<String, Object> map = new HashMap<>();

    public static void main(String[] args) {
        SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
        synchronizedDemo.test1();
    }


    public synchronized void test1() {
        System.out.println("再次加锁");
    }

}

Here you can see test1 methods are synchronized modification, we are locked on the record synchronizedDemo object is the object calls test1 method. So is the locking him.

Simple talk about the understanding of CAS

This belongs to an exclusive lock as synchronized pessimistic lock, it is certainly conflict in this place pessimistic locking of the task. In addition, after pessimistic locking, as well as optimistic locking, optimistic locking is the meaning of my optimistic that this place does not conflict, if conflict did not happen I will execute properly, if the conflict, I will try again.

CAS belongs optimistic locking.

To facilitate the understanding of CAS, we say that a typical example. Assume multiple threads execute this method increment, is bound to thread safety problems occur. Because i ++ not atomic operations, and increment method is not locked.

public class CASDemo {

    int i = 0;
    public void increment() {
        i++;
    }

}

There are two solutions, the first one we have just said certainly be locked by synchronized.

public class CASDemo {

    int i = 0;
    public synchronized void increment() {
        i++;
    }
  
      public static void main(String[] args) {
        CASDemo casDemo = new CASDemo();
        casDemo.increment();
    }
}

CasDemo here is to be locked, only one thread can be successful for casDemo lock, can counter +1 monitor his associated lock. Other threads will wait for the object to be released. Such is the draw in which multiple threads into a serialized, there will be loss of efficiency. Multiple threads in this queue.

The second way is to become i ++ atomic operations, how to do it java.util.concurrent.atomic large number of atoms of the object with the package, such as AtomicInteger.

public class CASDemo {

    AtomicInteger i = new AtomicInteger(0);

    public void increment() {
        i.incrementAndGet();
    }

}

Since the increment method only one line of command, but this method is atomic, then this method is not thread-safe natural problems.

See here a lot of guys will ask, you do not say CAS, how wander this up? Do not worry, ah, in front of all the bedding, I am not going to say a thing.

In fact incrementAndGet is a CAS operation. CAS stands for compare and set, compare and replaced. CAS idea is simple: three parameters, a current value of V memory, the expected value of the old A, B values ​​will be updated, if and only if the expected value of the A and V are the same memory value, the memory value is modified to B and return true, or do nothing and returns false. Its business logic principle shown in FIG.

CAS problems

  1. ABA problem

CAS needs to have time to check the operating values lower value has not changed, if not changed is updated, but if a value is A, became a B, he is a A, you'll find it when using CAS inspection the value does not change, but actually changed. This is the ABA problem CAS. Common Solutions is a version number. Append the version number in front of variables, each variable is updated when the version number plus one, then A-B-Ait will become 1A-2B-3A. Currently it offers a class in the JDK atomic package AtomicStampedReferenceto solve the ABA problem. The method of action of this class is compareAndSet checks the current reference is equal to the expected reference and the current mark is equal to the expected flag, if all equal Atomically the reference value and the flag is set to the given updated value.

  1. Large overhead long cycle time

Above we said that if CAS is not successful, it will spin in place, if a long spin will bring a very large CPU execution cost.

References "Java CAS principle to resolve"

Internet Java Engineer interview assault (third quarter)

"Java Concurrency become real."


Unfinished treatment

Guess you like

Origin www.cnblogs.com/joimages/p/12034752.html