当前位置:网站首页>Four pits in reentrantlock!
Four pits in reentrantlock!
2022-07-05 01:05:00 【Brother Lei talks about programming】
JDK 1.5 Before synchronized Its performance is relatively low , But in JDK 1.5 in , Officially launched a heavyweight feature Lock, Changed... In one fell swoop Java Middle lock pattern .JDK 1.5 When we talked about locks before , Only built-in locks can be used synchronized, But now we have an explicit lock in our lock implementation Lock.
In the previous article, we have introduced synchronized, See the following list for details :
《synchronized Lock this and class The difference between !》
《synchronized Lock expansion mechanism of optimization means !》
《synchronized Medium 4 An optimization , How many do you know? ?》
So let's focus on Lock.
Lock brief introduction
Lock It's a top-level interface , All its methods are shown in the figure below :
Its subclasses are listed below :
We usually use them ReentrantLock To define its instance , The relationship between them is shown in the figure below :
PS:Sync It means synchronous lock ,FairSync It's a fair lock ,NonfairSync Fair lock .
ReentrantLock Use
Learning any skill starts with using , So we are no exception , Let's take a look at ReentrantLock The basic use of :
public class LockExample {
// Create lock object
private final ReentrantLock lock = new ReentrantLock();
public void method() {
// Lock operation
lock.lock();
try {
// Business code ......
} finally {
// Release the lock
lock.unlock();
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
ReentrantLock After creation , There are two key operations :
- Lock operation :lock()
- Release lock operation :unlock()
ReentrantLock Pit in
1.ReentrantLock Default to unfair lock
A lot of people will think ( Especially novice friends ),ReentrantLock The default implementation is fair lock , Not really ,ReentrantLock By default, it is an unfair lock ( This is mainly due to performance considerations ), For example, the following code :
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// Create lock object
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// Define thread tasks
Runnable runnable = new Runnable() {
@Override
public void run() {
// Lock
lock.lock();
try {
// Print the name of the execution thread
System.out.println(" Threads :" + Thread.currentThread().getName());
} finally {
// Release the lock
lock.unlock();
}
}
};
// Create multiple threads
for (int i = 0; i < 10; i++) {
new Thread(runnable).start();
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
The results of the above procedures are as follows :
As can be seen from the results of the above execution ,ReentrantLock By default, it is an unfair lock . Because the name of the thread is incremented according to the order of creation , So if it's a fair lock , Then the execution of threads should be incremented in order , But from the above results, we can see , The execution and printing of threads are out of order , This explanation ReentrantLock By default, it is an unfair lock .
Want to ReentrantLock Setting a fair lock is also simple , Just create ReentrantLock when , Set up a true The construction parameters of , As shown in the following code :
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// Create lock object ( Fair lock )
private static final ReentrantLock lock = new ReentrantLock(true);
public static void main(String[] args) {
// Define thread tasks
Runnable runnable = new Runnable() {
@Override
public void run() {
// Lock
lock.lock();
try {
// Print the name of the execution thread
System.out.println(" Threads :" + Thread.currentThread().getName());
} finally {
// Release the lock
lock.unlock();
}
}
};
// Create multiple threads
for (int i = 0; i < 10; i++) {
new Thread(runnable).start();
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
The results of the above procedures are as follows :
As can be seen from the above results , When we explicitly give ReentrantLock Set up true After the construction parameters of ,ReentrantLock It becomes a fair lock , The order in which threads acquire locks has also become orderly .
Actually from ReentrantLock We can also see whether it is a fair lock or an unfair lock ,ReentrantLock Part of the source code implementation is as follows :
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
From the above source code can be seen , By default ReentrantLock Will create an unfair lock , If you explicitly set the value of the construction parameter to true when , It will create a fair lock .
2. stay finally Middle release lock
Use ReentrantLock Be sure to release the lock when , Otherwise, the lock will be occupied all the time , Other threads that use the lock will wait forever , So we're using ReentrantLock when , Must be in finally Middle release lock , This ensures that the lock will be released .
Counter example
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// Create lock object
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// Lock operation
lock.lock();
System.out.println("Hello,ReentrantLock.");
// An exception will be reported here , The lock cannot be released normally
int number = 1 / 0;
// Release the lock
lock.unlock();
System.out.println(" Lock released successfully !");
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
The results of the above procedures are as follows :
As can be seen from the above results , When an exception occurs, the lock is not normally released , This will cause other threads using the lock to be permanently waiting .
Example
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// Create lock object
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// Lock operation
lock.lock();
try {
System.out.println("Hello,ReentrantLock.");
// An exception will be reported here
int number = 1 / 0;
} finally {
// Release the lock
lock.unlock();
System.out.println(" Lock released successfully !");
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
The results of the above procedures are as follows :
As can be seen from the above results , Although there are exceptions in the method , But it doesn't affect ReentrantLock Lock release operation , In this way, other threads using this lock can acquire and run normally .
3. The lock cannot be released more than once
lock Number of operations and unlock The number of operations must correspond one by one , And a lock cannot be released multiple times , Because this will cause the program to report an error .
Counter example
once lock It corresponds to twice unlock operation , Cause the program to report an error and terminate the execution , The sample code is as follows :
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// Create lock object
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// Lock operation
lock.lock();
// Release the lock for the first time
try {
System.out.println(" Executive business 1~");
// Business code 1......
} finally {
// Release the lock
lock.unlock();
System.out.println(" Lock release lock ");
}
// Release the lock a second time
try {
System.out.println(" Executive business 2~");
// Business code 2......
} finally {
// Release the lock
lock.unlock();
System.out.println(" Lock release lock ");
}
// The last print operation
System.out.println(" Program execution complete .");
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
The results of the above procedures are as follows :
As can be seen from the above results , Execution section 2 individual unlock when , The program reported an error and terminated execution , The code that causes the exception does not execute normally .
4.lock Don't put it on try In code
In the use of ReentrantLock when , Be careful not to put the locking operation in try In the code , This will lead to the successful release of the lock without locking , This leads to abnormal program execution .
Counter example
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// Create lock object
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
try {
// This is abnormal
int num = 1 / 0;
// Lock operation
lock.lock();
} finally {
// Release the lock
lock.unlock();
System.out.println(" Lock release lock ");
}
System.out.println(" Program execution complete .");
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
The results of the above procedures are as follows :
As can be seen from the above results , If you put the locking operation on try In the code , It may lead to two problems :
- The lock is released successfully without locking , This leads to a new exception ;
- The exception of releasing the lock will overwrite the original exception of the program , This increases the difficulty of troubleshooting .
summary
This paper introduces Java Explicit locks in Lock And its subclasses ReentrantLock How to use and pay attention to ,Lock stay Java It occupies half of the lock , But in use, we should pay attention to 4 A question :
- By default ReentrantLock For a non fair lock, not a fair lock ;
- The number of locks added and released must be consistent , Otherwise, it will cause thread blocking or program exception ;
- The locking operation must be placed in try Before code , This can avoid the exception of successfully releasing the lock without locking ;
- The release lock must be placed in finally in , Otherwise, it will cause thread blocking .
Pay attention to the company 「Java Chinese community 」 See more interesting 、 Intellectual Java Concurrent articles .
Follow the QR code below , Subscribe to more .
author : Wang lei's blog
边栏推荐
- 全网最全正则实战指南,拿走不谢
- FEG founder rox:smartdefi will be the benchmark of the entire decentralized financial market
- BGP comprehensive experiment
- Discrete mathematics: propositional symbolization of predicate logic
- Implementation steps of master detail detail layout mode of SAP ui5 application
- [Yocto RM]10 - Images
- LeetCode周赛 + AcWing周赛(T4/T3)分析对比
- 有哪些收益稳定的理财产品,这两个都不错
- Grabbing and sorting out external articles -- status bar [4]
- 大专学历,33岁宝妈又怎样?我照样销售转测试,月入13k+
猜你喜欢
大专学历,33岁宝妈又怎样?我照样销售转测试,月入13k+
Operator explanation
What if the programmer's SQL data script coding ability is weak and Bi can't do it?
实战模拟│JWT 登录认证
Identifiers and keywords
BGP comprehensive experiment
leetcode518,377
“薪资倒挂”、“毕业生平替” 这些现象说明测试行业已经...
Visual explanation of Newton iteration method
潘多拉 IOT 开发板学习(RT-Thread)—— 实验4 蜂鸣器+马达实验【按键外部中断】(学习笔记)
随机推荐
[Yocto RM]10 - Images
Learn C language from scratch day 024
【C】 (written examination questions) pointer and array, pointer
Digital DP template
Take you ten days to easily complete the go micro service series (IX. link tracking)
[Yocto RM]11 - Features
Which financial products with stable income are good
Intel sapphire rapids SP Zhiqiang es processor cache memory split exposure
BGP comprehensive experiment
Basic concept and usage of redis
Paxos 入门
Detailed explanation of multi-mode input event distribution mechanism
Global and Chinese market of portable CNC cutting machines 2022-2028: Research Report on technology, participants, trends, market size and share
dotnet-exec 0.6.0 released
潘多拉 IOT 开发板学习(RT-Thread)—— 实验4 蜂鸣器+马达实验【按键外部中断】(学习笔记)
Hill sort of sorting
SAP UI5 应用的主-从-从(Master-Detail-Detail)布局模式的实现步骤
多模输入事件分发机制详解
NPM install error forced installation
Basic operation of database and table ----- phased test II