today , We began to Java High concurrency and multithreading , lock .

The last three , Basically speaking about some conceptual and basic things , It's a bit fragmented , But like liberal arts subjects , Just remember .

But this is the real cornerstone of high concurrency , It takes a lot of understanding and practice , One button one ring , Interlocking , It's not hard to , But it needs to be read carefully .

Okay , now .

-------------- The first part , Let's talk about it java The two keywords used to ensure the order between threads --------------

【synchronized】

synchronized yes Java One of the most common ways to solve concurrency problems in , It's also the simplest way .

synchronized Can guarantee java Atomicity in code blocks , Visibility and orderliness .

  • Java Visibility in the memory model 、 Atomicity and orderliness

visibility

It refers to the visibility between threads , The modified state of one thread is visible to another .

Atomicity

The atom is the smallest unit in the world , It is indivisible
All non atomic operations have thread safety problems , Sometimes we need to use synchronization technology (sychronized) To make it an atomic operation .
java Of concurrent Some atomic classes are provided under the package (AtomicInteger,AtomicLong,AtomicReference......), We'll talk about it later .

Orderliness

java Language provides volatile and synchronized Two keywords to ensure the order of operations between threads ;
volatile It itself contains " Disable instruction reordering " The semantics of the .

synchronized You can put any non null Object as " lock ".

synchronized There are three ways of using :

- When synchronized When acting on an example method , Monitor lock (monitor) Object instance (this);

- When synchronized When acting on a static method , Monitor lock (monitor) It's the object Class example , because Class Data exists in the permanent generation , So a static method lock is equivalent to a global lock of this class ;

- When synchronized When acting on an object instance , Monitor lock (monitor) It's an example of an object enclosed in parentheses ;

In general ,synchronized The scope of synchronization is as small as possible .

Because if it takes a long time , Then other threads must wait until the lock holding thread is finished .

if synchronized Method throws an exception ,JVM Will automatically release the lock , It doesn't cause deadlock problems .

When locking objects , You can't use String Constant , And basic types and encapsulation classes of basic types .

When objects are locked , To add final, Otherwise, the lock object changes , It could cause problems .

【volatile】

Java Language provides a weak synchronization mechanism , namely volatile Variable , Used to ensure that updates to variables are notified to other threads .

volatile Variable ensures the visibility of different threads when operating on this variable , That is, a thread changes the value of a variable , This new value is immediately visible to other threads .

from volatile When modifying variables, you will use the shared variables CPU Provided Lock Prefix instruction .

  1. Write the data of the current processor cache row back to system memory ;
  2. This write back operation will Tell me in other CPU The variables you get are invalid , The next time you use it, take it from the shared memory again .

When right and wrong volatile When variables are read and written , Each thread copies variables from memory to CPU In cache . If you have multiple computers CPU, Each thread may be in a different CPU Be dealt with on , This means that each thread can copy to a different CPU cache in .

When variables are declared as volatile After the type , Both compiler and runtime will notice that this variable is shared , Therefore, operations on this variable will not be reordered along with other memory operations .

volatile Variables are not cached in registers or invisible to other processors ,JVM Ensure that every time the variable is read from memory , skip CPU cache  This step , So reading volatile A variable of type always returns the most recently written value .

During a visit to volatile The lock operation is not performed on a variable , So the thread will not block execution , therefore volatile Variable is a kind of ratio sychronized Keyword more lightweight synchronization mechanism .

volatile The read performance consumption of is almost the same as that of ordinary variables , But the write operation is slower , Because it needs to insert many memory barrier instructions into the local code to ensure that the processor does not execute in disorder .

By volatile Modify the variable in the write operation , Will generate a special assembly instruction , This command triggers mesi agreement 「 Cache consistency protocol 」, There will be a bus sniffer mechanism , In short, this mechanism will constantly detect the change of the variable in the bus , If the variable changes , Because of this sniffing mechanism , Other cpu The value of the variable will be changed immediately cpu The cache data is emptied , Get this data from main memory again .

volitale Try to decorate simple types , Don't embellish reference types , because volatile Keyword changes to the basic type can be read consistently to multiple threads later , But for reference types such as arrays , Entity bean, Just make sure the visibility of references , But it doesn't guarantee the visibility of references .

Ensure thread visibility ;(MESI/CPU Cache consistency protocol for )

Disable instruction reordering .

laodfence Source language instruction

storefence Source language instruction

Double check in singleton mode , To add volatile.( The main reason is that the initialization order of the instance may be changed , In this way, the second thread may access the uninitialized instance ).

However, the above situation can only appear in the case of super high concurrency , In general, it is very difficult to appear , It's written here , It's for the students preparing for the interview .

  • synchronized and volatile

volatile The essence is to tell jvm Current variable in register ( The working memory ) The value in is uncertain , Need to read from main memory ;

synchronized Lock the current variable , Only the current thread can access this variable , Other threads blocked .

volatile Can only be used at variable level ;

synchronized You can use the 、 Method 、 And class level .

volatile Only variable modification visibility can be achieved , Atomicity is not guaranteed ; and synchronized It can ensure the visibility and atomicity of the variables .

volatile No thread blocking ;synchronized May cause thread blocking .

volatile Tagged variables are not optimized by the compiler ;synchronized Tagged variables can be optimized by the compiler .

-------------- The second part , Let's talk about all kinds of locks that are full of blogs --------------

【 Pessimistic locking · Optimism lock 】

  • Pessimistic locking

Always assume the worst , Every time you use data, you think someone else will modify it , So every time I get the data, I lock it .

So people who want to take this data will block it until it gets the lock ( Shared resources are used by only one thread at a time , Other threads are blocking , Transfer resources to other threads after use ).

There are many lock mechanisms used in traditional relational databases , For example, line locks. , Table lock, etc. , Read the lock , Write locks, etc. , It's all locked before the operation .

Java in synchronized and ReentrantLock Waiting for exclusive lock is the realization of pessimistic lock thought .

  • Optimism lock

Always assume the best , Every time I go to get the data, I think other people won't modify it , So it won't lock , But in the process of updating, we will judge whether other people have updated this data during this period , You can use the version number mechanism and CAS Algorithm implementation .

Optimistic lock is suitable for multi read applications , This can improve throughput , Similar to what the database provides write_condition Mechanism , In fact, they are all optimistic locks .

stay Java in java.util.concurrent.atomic The atomic variable class under the package is an implementation of optimistic lock CAS Realized .

The optimistic lock applies to Write less about , Because it saves a lot of lock overhead , But if you write more , May cause frequent retry operation , Instead, it reduces performance .

ABA problem , After two revisions , The actual value has been modified , But it didn't recognize .「 Also consider the citation , Although the pointer doesn't change , But the citation has changed 」

ABA problem ( The main problem is that there will be problems with the object , The basic type doesn't matter , You can add Version solve )

  • What is? CAS?

Compare and Swap, That is, compare and then exchange

Yes CAS The understanding of the ,CAS It's a lock free algorithm ,CAS Yes 3 Operands , Memory value V, Old expectations A, New value to modify B.

If and only if expected A And memory values V Phase at the same time , Put the memory value V It is amended as follows B, Otherwise, do nothing .

CAS The realization of depends on CPU The primitive language supports ( There's no interruption ).

If it's not equal , The shared data has been modified , Give up what you have done , Then do the operation again .

When there are few opportunities for synchronization conflicts , This assumption can lead to a large performance improvement .

  • Unsafe

Let's talk about this class briefly .

Java No direct access to underlying operating system , But through local (native) Method to access . But that's all ,JVM Or a back door , That's it Unsafe class , It provides hardware level atomic operations .

be-all CAS It's all used Unsafe To achieve the .

CAS Direct manipulation java The memory in the virtual machine .( You can go directly through the offset , Locate the value of a variable in memory , And then modify )「 That's why cas We can think of it as atomic 」

【 spinlocks 】

Thread blocking and wakeup needs CPU From user state to nuclear state , Frequent blocking and waking up to CPU It's a very heavy job , It will bring a lot of pressure to the concurrent performance of the system .

At the same time, we found that in many applications , The lock state of an object lock lasts only a short period of time , It's not worth it to block and wake up threads frequently for a short period of time .

When a thread tries to acquire a lock , If the lock is occupied by another thread , Just loop through the lock to see if it's released , Instead of going into thread suspend or sleep state .

Spin lock occupied CPU, But no access to the operating system ( Without going through the kernel state ), So it's always user mode .

Spin lock is suitable for the case that the critical area of lock protection is very small , If the critical area is small , The lock takes a short time .

The default number of spins is 10 Time , You can use the parameter -XX:PreBlockSpin To adjust .

【 Adaptive spin lock 】

If the thread spins successfully , So the next spin will be more , Because the virtual machine thinks that since it succeeded last time , So this spin is likely to succeed again , So it allows the spin wait to last a lot more .

conversely , If for a lock , Very few spins succeed , In the future, the number of spins will be reduced or even the spin process will be omitted , To avoid wasting processor resources .

-------------- The third part , Let's elaborate on developers and JVM For the lock of some optimization design and ideas --------------

【 Lock refinement 】

The refinement of locks is mainly divided into two aspects .

First of all ,synchronized The less content locked, the better , So in some cases , It may take some ( For example, section lock ,HASH lock , Weak reference lock, etc ) measures , Improve synchronization efficiency .

second ,synchronized The less code locked, the better , The less code , The longer the critical area is , The less time the lock will wait .

【 Lock coarsening 】

Normally speaking , For developers , The smaller the scope of the locked code, the better , But sometimes , We need to coarsen the lock .

It means to lock multiple consecutive locks 、 Unlock operations are linked together , Expand to a larger range of locks .

A series of continuous lock and unlock operations , May cause unnecessary performance loss .

【 Lock elimination 】

In order to ensure the integrity of the data , During the operation, it is necessary to control this part of the operation synchronously , But in some cases ,JVM No shared data race detected , This is a JVM Meeting Lock elimination of these synchronous locks .

The basis of lock elimination is Data support for escape analysis .

Such as :StringBuffer Of append Method .

StringBuffer.append() The lock is sb object . Virtual machine observation variables sb, It will soon be found that its dynamic scope is limited to concatString() Methods the internal .

That is to say sb All references to will never " The escape " To concatString() Out of the way , Other threads can't access it , So although there's a lock here , But it can be safely removed , After instant compilation , This code will ignore all synchronization and execute directly .

After the escape analysis , All objects will be allocated on the stack , Not from JVM In the memory model .

Escape analysis and lock elimination can use parameters respectively -XX:+DoEscapeAnalysis and -XX:+EliminateLocks( Lock removal must be in -server In mode ) Turn on .

【 Lock escalation 】

For locks , There are four states , No lock state , Biased lock state , Lightweight lock state , Heavyweight lock state .

1. When there is no competition , Bias lock is used by default .

   JVM Make use of CAS operation , On the object header Mark Word Partial setup thread ID, To indicate that this object is biased towards the current thread , So there's no real mutex involved .

2. If another thread tries to lock an object that has been biased ,JVM It needs to be withdrawn (revoke) Biased locking , And switch to lightweight lock implementation .

    Lightweight lock dependency CAS  operation Mark Word To attempt to acquire a lock , If retry is successful , Just use lightweight locks ;

3. Otherwise, it will be further upgraded to heavyweight lock after a certain number of spins .

  • Biased locking

Why introduce biased locks ?

Because after HotSpot The author of a large number of studies found that , Most of the time there is no lock competition , Often a thread gets the same lock multiple times , So if you have to compete for locks every time, it will increase a lot of unnecessary costs , To reduce the cost of acquiring locks , The biased lock introduced .

The deflection lock is in Single threaded execution of code blocks The mechanism used in this process , If in a multithreaded concurrent environment ( Threads A The synchronization code block has not been executed yet , Threads B Initiated a lock application ), It must be converted to a lightweight lock or a heavyweight lock .

Now almost all locks are re entrant , That is, the thread that has obtained the lock can lock many times / Unlock monitored objects .

According to the previous HotSpot Design , Lock every time / Unlocking involves a lot of CAS operation ( For example, the waiting queue CAS operation ),CAS Operations delay local calls ;

So the idea of biased locking is that once the thread gets the monitored object for the first time , And then let's watch the object " deviation " This thread , Subsequent calls can be avoided CAS operation , To put it bluntly, it is to set a variable 「 On the head of the object Mark Word Partial setup thread ID」, If it's found to be true You don't have to go through all kinds of locking / Unlock process .

The assumption to do this is based on the fact that in many scenarios , Most objects are locked by at most one thread in their life cycle , Using biased locks can reduce the non contention overhead .

The deflection lock is opened by default , And the start time is usually a few seconds slower than the application starts , If you don't want this delay , Then you can use -XX:BiasedLockingStartUpDelay=0;

If you don't want biased locks , So you can go through -XX:-UseBiasedLocking = false To set up ;

  • Lightweight lock

For most locks , There is no contention throughout the synchronization cycle , Lightweight lock usage CAS operation , Avoid using mutex .

If there is competition , Besides the cost of mutex , also CAS The operation of , Not only is there no promotion , On the contrary, the performance will decline

The scenario that lightweight locks are adapted to is when threads execute synchronization blocks alternately , If there is access to the same lock at the same time , It will inevitably lead to the expansion of lightweight locks into heavyweight locks .

  • Heavyweight lock

Synchronized It's through an internal object called a monitor lock (Monitor) To achieve .

Heavyweight locks don't take CPU.

But the essence of monitor lock depends on the underlying operating system Mutex Lock To achieve .

And the operating system to achieve the switch between threads, which needs to change from user state to kernel state , The cost is very high , The transition between States takes a relatively long time , That's why Synchronized The reason for low efficiency .

therefore , This depends on the operating system Mutex Lock The implemented lock is called " Heavyweight lock ".

notes : Locks can only be upgraded, not demoted .

  • contrast

lock

advantage

shortcoming

Applicable scenario

Biased locking

Lock and unlock do not need extra cost , It's almost as efficient as executing asynchronous methods

If there is lock contention between threads , Will cause additional lock revocation cost .

It is applicable to the scenario where only one thread accesses the synchronization block

Lightweight lock
「 spinlocks 」

Competing threads don't block , Improve the response speed of the program .

If you can't always get the thread of lock contention , It will consume all the time CPU.

Pursue response time ;
Synchronized block ( Lock code ) Short execution time , Fewer threads .

Heavyweight lock
「OS lock 」

Thread contention doesn't consume CPU

Thread blocking , Slow response time .

Pursue throughput ;
Synchronous blocks take a long time to execute , There are many threads .

-------------- The third part , Let's add some other concepts of locks that we didn't talk about , Complete the contents of the lock --------------

【 Other lock concepts 】

  • Section lock

Section lock (SegmentLock) It's simply fine-grained locking , Divide a lock into two or more segments , The thread locks and unlocks according to its own operation segment .

This avoids meaningless waiting between threads , Reduce the waiting time of threads . Common applications are ConcurrentHashMap, It implements internally Segment<K,V> Inherited ReentrantLock, Divided into 16 paragraph .

Of course , Actually in jdk1.8 in ,ConcurrentHashMap And start using CAS The way .

  • Exclusive lock - Shared lock

Exclusive locks are also called mutexes 、 An exclusive lock 、 Write lock , A lock can only be held by one thread at a time , Other threads must wait for the lock to be released before they can acquire it . Such as ReentrantLock.

Shared lock is also called read lock , It allows multiple threads to acquire a lock at the same time , A lock can be owned by multiple threads at the same time . for instance ReadWriteLock.

  • Fair lock

Fair lock is to follow the principle of first come first served , Multiple threads acquire locks in the order in which they apply for locks .

  • Reentrant lock

Re entrant lock means , Add method A After the lock is locked and locked, the method is called B, The method B You need locks, too , This can lead to deadlock , A reentrant lock causes the method to be called B The lock is automatically acquired when it is locked .

Java China is through lockedBy Field to determine whether the locked thread is the same .

synchronized It's a reentrant lock , It must also be a re entrant lock , otherwise There is no way for a subclass to call a parent's method .

There are many concepts , But remember , These not only need to be familiar with in the process of work , And I will be asked in the interview , So the students who are looking for a job recently , The content of the lock is the most important , We must read more, practice more and remember more .

In this article, we talk about the lock in multithreading , Almost all the lock related things are mentioned , But the depth is not enough , We'll talk about it in the next article JUC All kinds of synchronization lock under the , Later on , If you have the time , Will try to add some source code related analysis , Let's take a look at how these locks play from the implementation level .

As a programmer , No interest or enthusiasm , It's too hard to keep going , I hope the future of this series , Try to see the essence through the phenomenon as much as possible , Now write these trivial things , All floating on the surface , Dealing with jobs and interviews , Boring and boring .

Java High concurrency and multithreading ( Four )----- More about locks

  1. ( Reprint )java High concurrency :CAS The principle of no lock and its wide application

    java High concurrency :CAS The principle of no lock and its wide application   Copyright notice : This article is an original blog article , No reprint without the permission of the blogger , Reprint please indicate the source . The blogger's address is http://blog.csdn.net/liubenlong007 ...

  2. java High concurrent programming ( Four ) Some containers with high concurrency

    Excerpt from horse soldier java Concurrent video courses : One . Demand background : Yes N Train tickets , Each ticket has a number , At the same time there is 10 There are two windows selling tickets ,  Please write a simulation program . Analyze what problems may arise from the following program ? Repeat sales ? Overselling ? /** * ...

  3. Java Lock mechanism optimization under high concurrency

    This paper mainly talks about several ways of parallel optimization , Its structure is as follows : Lock the optimization Reduce lock holding time For example, avoid locking the entire method 1 public synchronized void syncMethod(){ 2 othercode ...

  4. Java High concurrent network programming ( Four )Netty

    In the process of network application development , Use it directly JDK Provided NIO Of API, More complicated , And want to improve performance , Also need to combine multithreading technology . Because of the complexity of network programming itself , as well as JDK API The development is more difficult to use , So in the open source community , Surge ...

  5. Java High concurrency and multithreading series - 1. Basic concepts of threads

    1. What is thread ? The difference between threads and processes Before you understand the concept of threads , We should know what process is first ? Process is one of the basic concepts of operating system , It's an instance of the program being executed . * Here are some of the basic concepts of process ------- ...

  6. Java High concurrent programming ( Four )

    One .Executor actuator 1.Executor Interface ,java Top level interface in thread pool framework , Provide a execute Method to perform the task import java.util.concurrent.Executor; ...

  7. java High concurrency and multithreading

    The difference and connection between process and thread From resource consumption , Switching efficiency , Communication mode, etc Threads have many of the characteristics of traditional processes , It is also called light process (Light—Weight Process) Or process : The traditional process is called heavy process (H ...

  8. java High concurrency series - The first 16 God :JUC Tool class waiting for multithreading to complete CountDownLatch, Necessary skills

    This is a java High concurrency series 16 An article . Content of this article Introduce CountDownLatch And usage scenarios Several examples are provided CountDownLatch Use Write a tool class for parallel tasks If there is such a need , When we ...

  9. 【 actual combat Java High concurrency programming 6】 Challenge lock free algorithm : No lock Vector Realization

    [ actual combat Java High concurrency programming 1]Java The pointer in :Unsafe class [ actual combat Java High concurrency programming 2] Lock free object references :AtomicReference [ actual combat Java High concurrency programming 3] Objects with timestamps ...

  10. 【 actual combat Java High concurrency programming 4】 Arrays can also be unlocked :AtomicIntegerArray

    In addition to providing basic data types ,JDK We have also prepared arrays and other composite structures for us . The currently available arrays of atoms are :AtomicIntegerArray.AtomicLongArray and AtomicReferenceArray, Separate table ...

Random recommendation

  1. RabbitMQ What will be monitored IP from localhost Change to specify IP

    # vim /etc/rabbitmq/rabbitmq.config Search for tcp_listeners Change to :{tcp_listeners, [{" designated IP", 5672}] ...

  2. WWDC2016 A little bit of personal thought

    I saw the news and WWDC, It's hard for individual game developers to get along with it ,WWDC Inside iMessage Information revealed , I feel that wechat has competitors , If Apple put iMessage Build a wechat model ( Chat + Third party access ), ...

  3. Commonly used http Request status code meaning

    1**  ---- Temporary response 2**  ---- Successful response 3**  ---- Redirect 4**  ---- Request error 5**  ---- Server error The common ones are as follows : 200--- The server successfully returned to the web page 301-- ...

  4. ubuntu Next use apt-get install Which directory is the installed software in

    Form like apt-get install apps Such an order , The download file is usually placed in /var/cache/apt/archives Under the table of contents , Then install . If not cleaned up in time , This directory will take up more and more space , Fortunately, ...

  5. fread(),fwrite() read / Write stream

    C Library function - fread() describe C Library function size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) From a given stream strea ...

  6. my Android 4 Learn how to use the series Internet resources

    Catalog Connect Internet resources analysis XML resources Use Download Manager Download the file Inquire about Download manager Use Account Manager Yes Google App Eng ...

  7. STL-Deque Source analysis

    G++ ,cygnus\cygwin-b20\include\g++\stl_deque.h A complete list /* * * Copyright (c) 1994 * Hewlett-Packard Comp ...

  8. Turn the form of flow into Base64

    public class Test2 { public static String get() throws IOException { InputStream resourceAsStream = ...

  9. pc End font size calculation and echart Font size calculation in

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  10. Html And CSS Study the book list

    1.Head First HTML And CSS( The second edition ) Douban details This book is very suitable for beginners HTML And CSS Its content is not necessarily detailed , But it must be your first choice . Introduced as a book Book translation is OK . At present, Douban score 9.3.