When we talk about synchronized, and what are we talking about?

synchronized is what to do with?

Java is a synchronized manner to achieve lock, we can give a method, a property, and other resources for locking an object through synchronized to.

Why do we need to lock it?

You might say, because when a resource is accessed by multiple threads, we need to synchronize to coordinate thread access the order, in this case, we want to lock the resource.

For example, during the release train ticket to prohibit access to the conductor votes, this is essentially a resource (ticket source) lock, coordinated the operation sequence conductor and administrator.

If you explain to the layman, to say enough. But for a technology people have the attitude of, this description would be too simple and obvious. This problem, we had to start from the source.

We used a piece of code to express the above example:

//火车票程序
public class TrainTicket {
  int beiJing = 0, shangHai = 0;
  
  //放票
  public void writer() {
    beiJing = 1;
    shangHai = 2;
  }

  //查票
  public void reader() {
    int r1 = beiJing;
    int r2 = shangHai;
  }
}
复制代码
//T-1 放票线程
recordering.writer();
复制代码
//T-2 查票线程
recordering.reader();
复制代码

We press the "order" execution T1 and T2, what result would it be? We expect results r1 = 1, r2 = 2 but the result is likely to be r1 = 0, r2 = 0 may also be r1 = 1, r2 = 0 may also be ...

Why do we expect results and not the same as it is where is the problem?

This is what we want to focus on that today a concept - reordering

Reordering (Reordering) is a policy compiler (Compiler) in order to optimize the efficiency and do. In a single-threaded, the reordering to ensure that does not affect the semantics of the program, so for no dependencies statements are likely to be reordered. such as

int a=0;
int b=1;
复制代码

The first statement and the statement does not constitute a second row dependent, so the compiler can arbitrarily change the order.

Focus here, so in a multi-thread environment, when it comes to reordering, will encounter thread-safety issues. Therefore, Java compiler does not guarantee thread safety, whether thread safety ensured by the programmer.

This is not a rejection of pot thing! ! !

What way is this pot programmers!

Well, let's go back to the original question: how to better scapegoat?

Oh, no.

Why do we need a shared resource lock?

Knock on the blackboard, draw the focus

Locking thread-safety issues in order to eliminate the program has generated reordering, and ultimately ensure consistency and semantic consistency of data!

Speaking of which, it seems to say more clearly, but there is a fundamental problem

When we use the synchronized (lock), how you can do it thread safe?

happen-before principle

It defines a set of principles happen-before in the Java memory model (JMM), a specific description of how this principle, the author is not good grasp, if insisted on a definition, then I think: happen-before is provided by a series of Java the local order to ensure the rule. More specific point is, if A happens-before operating the B operation, then it means that the operating results for B of A is visible.

We can go back to understand how the train example, if the ticket operation happens-before to check the ticket operation, then the result of the vote is checked for visible certain, that the election results will be found correct .

The following are specific rules of each

  • Each action in a thread happens before every action in that thread that comes later in the program's order.
  • An unlock on a monitor happens before every subsequent lock on that same monitor.
  • A write to a volatile field happens before every subsequent read of that same volatile.
  • A call to start() on a thread happens before any actions in the started thread.
  • All actions in a thread happen before any other thread successfully returns from a join() on that thread.

There are rules in Chinese online a lot, the reason I posted in English, mainly on account of the provisions of this anyway, no one would remember, but rather English the official document posted more appropriate, but also to help the students to want to check the official document.

For the second (on lock) rules extend it. With a lock unlock operation before the lock, that is a lock in the locked state, you must first perform the unlock operation can be carried out behind lock operation.

Officially because of this rule, we can achieve by locking thread-safe way to transform what the code above

//火车票程序
public class TrainTicket {
  int beiJing = 0, shangHai = 0;
  
  //放票
  public synchronized void writer() {
    beiJing = 1;
    shangHai = 2;
  }

  //查票
  public synchronized void reader() {
    int r1 = beiJing;
    int r2 = shangHai;
  }
}
复制代码

In this way, the two methods are combined with lock, thus achieving a security thread.

The compiler did what?

After synchronized code block of instructions the compiler generates a monitorenter and monitorexit one or more instructions, as follows:

monitorenter
/*---------*/
     code
/*--------*/
monitorexit
复制代码

For monitorenter and monitorexit, we can understand each lock object has a lock counter and a pointer to the thread that holds the lock.

When performing monitorenter instruction, if the target object's lock counter is zero, then that it is not held by another thread, in this case, Java virtual machine thread holding the lock object is set to the current thread, and the counter plus 1.

In the case of the target object's lock counter is not equal to zero, if other threads access, you need to wait until the thread holding the lock releases the lock. (Think about the second rule happen-before in)

Written in the last

There are several issues is extensible

1, the reordering has three dimensions, respectively, compiler, memory and processor. Herein refers only to the compiler reordered, but no mention reordering memory.

2, from the memory dimension, is how to stop the reordering?

3, happen-before principles mentioned in the volatile type variable, this type of variable anything extraordinary, what can we do to solve it?

Next time to dwell on

Original article, reproduced please indicate the source

Cited references (reference):

www.cs.umd.edu/~pugh/java/… docs.oracle.com/javase/spec…

Guess you like

Origin juejin.im/post/5d0f3c9cf265da1bcd37e1ee