current position:Home>2021-06-05 Java Foundation (day four): two ways of locking

2021-06-05 Java Foundation (day four): two ways of locking

2022-05-15 05:13:07InfoQ

You can see in the lock The previous code can be executed by other threads , however lock The following code must wait for the previous thread to release the lock before it can be executed , There will be a blockage

What we should pay attention to here is , Each object will have its own ReentrantLock, So compete for the same ReentrantLock Object will block , The lock can ensure serial access , If it's two different objects , Take the above chestnuts as an example , It's just two different TestSyncFunny object , Then the two threads get different locks , There will be no blocking

This lock is called a reentrant lock (ReentrantLock: Reentrant ),
Because this lock can be obtained repeatedly by the thread
, The lock will have a hold count to track the pair lock Nested use of methods , That is, in the locked try Call a method in a statement block A, The method A With the same lock ( The same ReentranLock), So get B The lock will also affect A Operation of

Take a chestnut

private Ree 
《 A big factory Java Analysis of interview questions + Back end development learning notes + The latest architecture explanation video + Practical project source code handout 》 Free open source Prestige search official account 【 Advanced programming 】
 ntrantLock lock = new ReentrantLock();

public void doSyncTo(String name){

System.out.println(" below "+name+" Also lock ");

lock.lock();

try{

System.out.println(name+" It's locked ~~~~");

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public void doSync(String name){

System.out.println(name+" It hasn't been locked yet ----");

lock.lock();

try{

System.out.println(name + " It's locked ,dododoodid");

doSyncTo(name);

System.out.println(name+" After calling another locking method , And the lock has been released ");

Thread.sleep(2000);

System.out.println(name+" I wake up ");

//code....

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

Above are two locking methods , It's all the same ReentrantLock, And in doSync In the method , Also called doSyncTo Methods

null
You can see , call doSync To get the ReentrantLock, Will make other threads unable to call doSyncTo Those methods after locking ,
You have to wait until the thread releases the outermost lock , namely doSync Of lock Can be called , Released alone doSyncTo Inside lock It's not enough
[](() Fair lock
We can also use ReentrantLock To build a fair lock

Call the following constructor , Pass in true Parameters

null
Fair lock means :
When the lock is released , It tends to let the thread with the longest wait time acquire the lock

However, fair locks can affect performance , So it's generally unfair , And the fair lock is not necessarily absolutely fair , It also depends on the thread scheduler ,
If the thread scheduler ignores a thread that has been waiting for a lock for a long time , Then we can't achieve fairness
[](() Conditions of the object
Suppose a thread enters
A critical region
after , need
Wait for other threads to complete some operations before continuing
, So if this thread gets ReentrantLock, Then other threads can't get ReentrantLock, Cannot execute command , It is impossible to complete the specified operation , Let the thread that got the lock continue to execute , So how to solve this situation

The solution to this is , Let the thread pause now , And give up holding the lock , Let other threads complete the operation , When the conditions are met , The thread can be reactivated ,
Do the following from where you paused
.

So we can add a condition object to it , When the conditions are not met , Let the thread wait here and release the lock , When the conditions are met , And when the lock is available , The thread will not immediately compete for the lock and become a runnable state , Then do the rest , It is
When another thread also determines whether the condition is met , Will reactivate all threads waiting for this condition ( These threads cannot activate themselves )
, Because of this , Often leads to
Deadlock
The scene of , Suppose the thread that modifies the condition is blocked , The thread waiting for the condition is changed await, Then both threads are finished

Get condition object

null
The condition object is a Condition, call await Method can enter
Wait set of threads ( Wait for the conditions to be met and activated )
in , When the conditions are met , Another thread that makes the same judgment ( Also entered while(number < 9) The thread of ) will
Deactivate all threads in the wait set , Then these threads can grab the lock , Only after you grab the lock can you continue to execute from the suspended place

about ReentrantLock You can use multiple conditional objects , Thus, different thread waiting sets are formed

[](()synchronized keyword

from java1.0 Version start ,Java Each object in has an internal lock , It also becomes an internal object lock , Use synchronized keyword

Using this keyword, you don't have to use a reentry lock explicitly (ReentrantLock), Internal object locks can only be associated with one condition , That is, there is only one condition object ( The difference in ReentrantLock There can be multiple conditional objects )

The methods related to the corresponding condition object are as follows

copyright notice
author[InfoQ],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/131/202205111301205540.html

Random recommended