当前位置:网站首页>Understand the locks that can't

Understand the locks that can't

2022-07-24 00:55:00 wzf6667


Java Multithreading wait() Methods and notify() Method

These two methods appear and are used in pairs , To implement these two methods , There is a premise that , The current thread must get its object's monitor( Be commonly called “ lock ”), Otherwise it will throw IllegalMonitorStateException abnormal , So these two methods must be called in the synchronization block code .

Reentrant lock

You can get your own internal lock again . For example, a thread obtains the lock of an object , At this time, the object lock has not been released , When it wants to acquire the lock of this object again, it can still acquire , If it's not lockable for re-entry , It causes a deadlock . The same thread gets the lock every time , The counters of the lock are all self increasing 1, So wait until the lock counter goes down to 0 To release the lock .

Deadlock of non reentrant lock

Non reentrant locks cause deadlocks : Threads A Have , Threads B Waiting for the , At this point, the thread A The method in calls again , If it is not reentrant ,A The method of cannot be executed, so the lock is not released ,B If you don't get it, you can't implement it , It causes a deadlock .

Fair lock and unfair lock

Fair lock

It indicates that the order in which the thread obtains the lock is allocated according to the order in which the lock is added , And first come, first served , First in, first out .

Not fair lock

Represents the preemption mechanism for obtaining locks , It's a random acquisition of locks , Unlike the fair lock, the one who comes first may not get the lock ,
It's possible that I can't get the lock all the time , So the result is unfair .
It's like a group of people waiting to withdraw money , Everyone queuing to withdraw money is a fair lock , Who is the first to get ATM It's unfair who takes the money first .

synchronized and ReentrantLock Method difference

Master the basic knowledge of the above lock , Let's take a look at two different ways to implement locks (java guide) link : link.
① Both are reentrant locks

Both are reentrant locks .“ Reentrant lock ” The concept is : You can get your own internal lock again . For example, a thread obtains the lock of an object , At this time, the object lock has not been released , When it wants to acquire the lock of this object again, it can still acquire , If it's not lockable for re-entry , It causes a deadlock . The same thread gets the lock every time , The counters of the lock are all self increasing 1, So wait until the lock counter goes down to 0 To release the lock .

② synchronized Depend on JVM and ReentrantLock Depend on API

synchronized It depends on JVM Realized , We also talked about The virtual machine team is in JDK1.6 by synchronized Keywords are optimized a lot , But these optimizations are all implemented at the virtual machine level , Not directly exposed to us .ReentrantLock yes JDK Level realized ( That is to say API level , need lock() and unlock() Method coordination try/finally Statement block to complete ), So we can check its source code , See how it works .

③ ReentrantLock Than synchronized Added some advanced features

comparison synchronized,ReentrantLock Added some advanced features . There are mainly three points :① Wait for interruptible ;② Fair lock can be achieved ;③ Optional notification can be achieved ( Locks can bind multiple conditions )

ReentrantLock Provides a mechanism to interrupt threads waiting for locks , adopt lock.lockInterruptibly() To implement this mechanism . That is to say, the waiting thread can choose to give up waiting , Deal with other things instead .
ReentrantLock You can specify whether the lock is fair or not . and synchronized Only unfair lock . The so-called fair lock is that the thread waiting first obtains the lock first . ReentrantLock The default is not fair , Can pass ReentrantLock Class ReentrantLock(boolean fair) Construct methods to determine whether it is fair .
synchronized The key words and wait() and notify()/notifyAll() The combination of methods can realize waiting / A notification mechanism ,ReentrantLock Class, of course , But with the help of Condition Interface and newCondition() Method .Condition yes JDK1.5 Only after that , It has good flexibility , For example, multiple notifications can be implemented in one Lock Object can create multiple Condition example ( Object monitor ), Thread objects can be registered in the specified Condition in , In this way, thread notification can be carried out selectively , More flexible on scheduling threads . In the use of notify()/notifyAll() Method for notification , The thread to be notified is by JVM Select the , use ReentrantLock Class combination Condition Instances can implement “ Selective notice ” , This function is very important , And it's Condition The interface is provided by default . and synchronized Keywords are equivalent to the whole Lock There is only one object Condition example , All threads are registered on one of them . If you execute notifyAll() Method will notify all threads in the waiting state, which will cause great efficiency problems , and Condition Example of signalAll() Method Will only wake up registration in this Condition All waiting threads in the instance .
If you want to use the above functions , So choose ReentrantLock It's a good choice .
( My understanding is that synchronized Wake up (notify) Cannot specify which thread to wake up , and ReentrantLock Can combine condition Instance implements selective notification .)
④ Performance is no longer the standard of choice

volatile keyword

2.1. Let's talk about Java Memory model

stay JDK1.2 Before ,Java The memory model implementation is always from main memory ( Shared memory ) Read variables , There is no need for special attention . And in the present Java Memory model , Threads can save variables to local memory ( For example, the machine register ) in , Instead of reading and writing directly in main memory . This may cause a thread to modify the value of a variable in main memory , Another thread continues to use copies of its variable values in registers , Cause data inconsistency .
To solve this problem , You need to declare the variable as volatile, This is the instruction JVM, This variable is not stable , Every time I use it, I read it in main memory .

To put it bluntly , volatile The main function of keywords is to ensure the visibility of variables, and then another function is to prevent the reordering of instructions .

2.2 Three important features of concurrent programming

Atomicity : One or more operations , Or all operations will be executed and will not be interrupted by any interference , Or all operations are performed , Either not .synchronized Can guarantee the atomicity of the code fragment .
visibility : When a variable modifies a shared variable , Then other threads can immediately see the latest value after modification .volatile Keywords guarantee the visibility of shared variables .
Orderliness : The sequence of code execution ,Java Optimization in compiler and runtime , The order in which code is executed is not necessarily the order in which code is written .volatile Keywords can prevent instructions from reordering optimization .

2.3. say something synchronized Key words and volatile The difference between keywords

synchronized Key words and volatile Keywords are two complementary beings , Instead of being antagonistic :

volatile Keyword is a lightweight implementation of thread synchronization , therefore volatile Performance is definitely better than synchronized Keywords are better . however volatile Keywords can only be used for variables and synchronized Keywords can modify methods and code blocks .synchronized The key word in JavaSE1.6 After that, it mainly includes biased lock and lightweight lock introduced to reduce the performance consumption caused by lock acquisition and lock release, as well as other various optimizations, and the execution efficiency has been significantly improved , Used in actual development synchronized There are more scenarios for keywords .
Multithreaded access volatile Keywords don't block , and synchronized Keywords may block
volatile Keywords ensure data visibility , But it doesn't guarantee the atomicity of the data .synchronized Keywords both guarantee .
volatile Keyword is mainly used to solve the visibility of variables among multiple threads , and synchronized Keyword solves the synchronization of accessing resources among multiple threads .
link : link.
Atomicity : Do you want to finish running or don't run .synchronized To ensure the cpu After the time slice runs out , Do not release the lock object , Other threads cannot acquire locks , Wait until the current thread gets the time slice again , Can continue from the current code ( Program counter ).

原网站

版权声明
本文为[wzf6667]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/204/202207230539508668.html