当前位置:网站首页>Multithreading and high concurrency (9) -- other synchronization components of AQS (semaphore, reentrantreadwritelock, exchanger)
Multithreading and high concurrency (9) -- other synchronization components of AQS (semaphore, reentrantreadwritelock, exchanger)
2022-07-07 07:00:00 【The green flowers of the Li Wang family】
jdk except CountDownLatch、CyclicBarrier、Phaser Several very useful concurrency tool classes are also provided :Semphore、Exchanger、ReentrantReadWriteLock, This article will explain , At the same time, I will summarize LockSupport usage .
One 、Semphore( Signal lamp )
Semphore Allow several threads to execute at the same time , Light up and execute , Do not execute when the light is off . Its main function is to Current limiting . The code is as follows :
public static void main(String[] args) {
// The number of threads that can only be executed at a time 20.
final Semaphore semaphore = new Semaphore(20);
// Specified number of threads
ExecutorService threadPool = Executors.newFixedThreadPool(30);
for (int i = 0; i < 30; i++) {
int finalI = i;
threadPool.execute(() ->{
try {
semaphore.acquire(5);// obtain 5 Permission , So the number of runnable threads is 20/5=4
Thread.sleep(1000);
System.out.println(" vehicle :" + finalI+" adopt ");
Thread.sleep(1000);
semaphore.release(5);// Release 5 Permission
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
threadPool.shutdown();
}
The result of the operation is that only 4 Threads through .
tryAcquire() Method : Try to get a token , Returns the success or failure of obtaining the token , Do not block threads .
Semaphore There are two patterns , Fair model and unfair model .
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
Semaphore And CountDownLatch equally , It is also an implementation of shared lock . It is constructed by default AQS Of state by permits. When the number of threads executing a task exceeds permits, Then the extra threads will be put into the blocking queue Park, And spin judgment state Is it greater than 0. Only when state Greater than 0 When , Blocked threads can continue to execute , At this point, the thread that previously executed the task continues to execute release() Method ,release() The method makes state And the variable of will add 1, Then the spinning thread will judge success . such , There's no more than permits Number of threads can spin successfully , This limits the number of threads that execute tasks .
Two 、ReentrantReadWriteLock
When reading and writing , Read between threads does not need to be exclusive , Writing requires exclusivity to avoid bias in the results . At this time, read-write separation is required . Read the previous article on Multithreading , We also know the meaning of exclusive lock and shared lock . At this time, read locks are shared locks , Write locks are exclusive locks, also known as mutexes .
ReadWriteLock There are two internal approaches readLock and writeLock,ReetrantReadWriteLock Realized ReadWriteLock Interface , Added reentrancy and supports fair and unfair modes .ReadWriteLock Supporting lock degradation is to change from write lock to read lock , Lock upgrade is not supported, that is, from read lock to write lock .
The sample code is as follows :
static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// Write lock
private static void write(String name) {
readWriteLock.writeLock().lock();
try {
Thread.sleep(1000);
System.out.println(name + " Start signing ");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readWriteLock.writeLock().unlock();
}
}
// Read the lock
private static void read(String name) {
readWriteLock.readLock().lock();
try {
Thread.sleep(1000);
System.out.println(name + " Start reading ");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
int finalI = i;
new Thread(() -> {
write(" Small " + finalI);
}, " Small " + i).start();
}
for (int i = 0; i < 5; i++) {
int finalI = i;
new Thread(() -> {
read(" Small " + finalI);
}, " Small " + i).start();
}
}
The end result is that the write lock will write one by one , Sequential execution , The read lock is executed at the same time in the macro .
3、 ... and 、Exchanger
Exchanger The function of is to make 2 Exchange data between threads , And it's two-way . A thread called exchange( ) Method exchange data , Synchronization point reached , Then it will keep blocking and waiting for another thread to call exchange( ) Method to exchange data . For example, two people exchange equipment in the game , It must be exchanged .
public V exchange(V x) throws InterruptedException
Wait for another thread to reach this swap point ( Unless the current thread is interrupted ), Then pass the given object to the thread , And receive the object of the thread .
public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException
Wait for another thread to reach this swap point ( Unless the current thread is interrupted , Or the specified waiting time is exceeded ), Then pass the given object to the thread , Receive the object of this thread at the same time .
The sample code is as follows :
static Exchanger<Object> exchanger = new Exchanger<>();
static String a = "aaaaa";
static String b = "bbbbbbbbbb";
public static void main(String[] args) {
new Thread(()->{
System.out.println(" The rope 1 Number ");
try {
Object exchange = exchanger.exchange(a);
System.out.println(" The rope 1 Number revicer data : " + exchange.toString());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
System.out.println(" Daji 2 Number ");
try {
Object exchange = exchanger.exchange(b);
System.out.println(" Daji 2 Number revicer data : " + exchange.toString());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
The operation results are as follows :
The rope 1 Number
Daji 2 Number
Daji 2 Number revicer data : aaaaa
The rope 1 Number revicer data : bbbbbbbbbb
It can be seen that Yasuo and Daji are waiting before exchanging data , Start running after exchanging data .
Four 、LockSupport
LockSupport The main function is to block and wake up threads .
The main methods are as follows :
public static void park() {
UNSAFE.park(false, 0L);
}
//blocker It is used to record who is blocked when a thread is blocked . For thread monitoring and analysis tools to locate causes .
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(false, 0L);
setBlocker(t, null);
}
public static void unpark(Thread thread) {
if (thread != null)
UNSAFE.unpark(thread);
}
You can see that it calls Unsafe class , Is involved CPU Primitives , There is no further study here .
Since it blocks and wakes up threads , Let's take a look first wait()、notify() Method , The code is as follows :
private static Object obj = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (obj) {
System.out.println("wait Let's start with !");
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait After that !");
}
}).start();
new Thread(() -> {
synchronized (obj) {
System.out.println("notify Later on !");
obj.notify();
System.out.println("notify End of the first !");
}
}).start();
}
The operation results are as follows :
wait Let's start with !
notify Later on !
notify End of the first !
wait After that !
Obvious , These two methods must first obtain the lock object , That is, they must use in synchronized code blocks ; and notify Only one thread can be randomly selected to wake up , Unable to wake the specified thread .
But for the code above , How long after execution , If notify() What if you implement it first ?wait() It'll keep blocking .
about LockSupport Of park() and unpark() Methods? , There is no consideration in this regard . Its usage is as follows :
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println(" It's starting to jam !");
LockSupport.park();
System.out.println(" The jam is over !");
});
thread1.start();
Thread.sleep(1000);
System.out.println(" It starts to wake up !");
LockSupport.unpark(thread1);
System.out.println(" The end wakes up !");
}
The operation results are as follows :
It's starting to jam !
It starts to wake up !
The end wakes up !
The jam is over !
It can be seen that the first is blocking , Then wake up and end the blocking .
LockSupport Than Object Of wait/notify There are two advantages :
LockSupport It doesn't need to be in the synchronization code block , The decoupling between threads is realized .
unpark() Can precede park call , So there is no need to worry about the order of execution between threads . The code is as follows :
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new MyThread();
thread1.start();
System.out.println(" It starts to wake up !");
LockSupport.unpark(thread1);
System.out.println(" The end wakes up !");
}
static class MyThread extends Thread{
@Override
public void run() {
System.out.println(" It's starting to jam !");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LockSupport.park();
System.out.println(" The jam is over !");
}
}
Thread.sleep(1000); Let the main thread run first , First unpark(), The final results are as follows , Not blocked :
It starts to wake up !
It's starting to jam !
The end wakes up !
The jam is over !
边栏推荐
- Jetpack compose is much more than a UI framework~
- 请教一个问题,flink oracle cdc,读取一个没有更新操作的表,隔十几秒就重复读取全量数据
- 【mysqld】Can't create/write to file
- 如何给目标机器人建模并仿真【数学/控制意义】
- Programmers' daily | daily anecdotes
- 【从零开始】win10系统部署Yolov5详细过程(CPU,无GPU)
- MySql用户权限
- 企业如何进行数据治理?分享数据治理4个方面的经验总结
- Please ask a question, flick Oracle CDC, read a table without update operation, and repeatedly read the full amount of data every ten seconds
- 一文带你了解静态路由的特点、目的及配置基本功能示例
猜你喜欢
场馆怎么做体育培训?
POI export to excel: set font, color, row height adaptation, column width adaptation, lock cells, merge cells
BindingException 异常(报错)处理
途家、木鸟、美团……民宿暑期战事将起
.net core 访问不常见的静态文件类型(MIME 类型)
[noi simulation] regional division (conclusion, structure)
MATLAB小技巧(30)非线性拟合 lsqcurefit
From zero to one, I will teach you to build the "clip search by text" search service (2): 5 minutes to realize the prototype
从零到一,教你搭建「CLIP 以文搜图」搜索服务(二):5 分钟实现原型
Mysql---- import and export & View & Index & execution plan
随机推荐
Answer to the first stage of the assignment of "information security management and evaluation" of the higher vocational group of the 2018 Jiangsu Vocational College skills competition
Pinduoduo lost the lawsuit: "bargain for free" infringed the right to know but did not constitute fraud, and was sentenced to pay 400 yuan
Data of all class a scenic spots in China in 2022 (13604)
DB2获取表信息异常:Caused by: com.ibm.db2.jcc.am.SqlException: [jcc][t4][1065][12306][4.25.13]
How Oracle backs up indexes
Linear algebra (1)
Several index utilization of joint index ABC
[GNN] graphic gnn:a gender Introduction (including video)
请问 flinksql对接cdc时 如何实现计算某个字段update前后的差异 ?
2022年全国所有A级景区数据(13604条)
Bus message bus
二十岁的我4面拿到字节跳动offer,至今不敢相信
Kotlin之 Databinding 异常
Stack and queue-p78-8 [2011 unified examination true question]
7天零基础能考证HCIA吗?华为认证系统学习路线分享
ViewModelProvider.of 过时方法解决
Get the city according to IP
【NOI模拟赛】区域划分(结论,构造)
mobx 知识点集合案例(快速入门)
工具类:对象转map 驼峰转下划线 下划线转驼峰