当前位置:网站首页>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 !
边栏推荐
- 中英文说明书丨ProSci LAG-3 重组蛋白
- 学术报告系列(六) - Autonomous Driving on the journey to full autonomy
- 健身房如何提高竞争力?
- 什么情况下考虑分库分表
- This article introduces you to the characteristics, purposes and basic function examples of static routing
- MATLAB小技巧(30)非线性拟合 lsqcurefit
- 企业如何进行数据治理?分享数据治理4个方面的经验总结
- Postgresql源码(60)事务系统总结
- Cloudcompare point pair selection
- MySQL installation
猜你喜欢
随机推荐
Jetpack compose is much more than a UI framework~
网络基础 —— 报头、封装和解包
Under what circumstances should we consider sub database and sub table
Algorithm --- bit count (kotlin)
Mysql---- import and export & View & Index & execution plan
Performance comparison between Ceres solver and g2o
偏执的非合格公司
Learning records on July 4, 2022
Abnova 免疫组化服务解决方案
「运维有小邓」符合GDPR的合规要求
精准时空行程流调系统—基于UWB超高精度定位系统
隐马尔科夫模型(HMM)学习笔记
二十岁的我4面拿到字节跳动offer,至今不敢相信
unity3d学习笔记
一条慢SQL拖死整个系统
一文带你了解静态路由的特点、目的及配置基本功能示例
Stack and queue-p79-10 [2014 unified examination real question]
联合索引ABC的几种索引利用情况
Learning notes | data Xiaobai uses dataease to make a large data screen
2018年江苏省职业院校技能大赛高职组“信息安全管理与评估”赛项任务书第二阶段答案